00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 #include <ptlib.h>
00513
00514 #ifdef __GNUC__
00515 #pragma implementation "channels.h"
00516 #endif
00517
00518 #include "channels.h"
00519
00520 #include "h323pdu.h"
00521 #include "h323ep.h"
00522 #include "h323rtp.h"
00523
00524
00525
00526 #define MAX_PAYLOAD_TYPE_MISMATCHES 8
00527 #define RTP_TRACE_DISPLAY_RATE 16000 // 2 seconds
00528
00529
00530 class H323LogicalChannelThread : public PThread
00531 {
00532 PCLASSINFO(H323LogicalChannelThread, PThread)
00533 public:
00534 H323LogicalChannelThread(H323EndPoint & endpoint, H323Channel & channel, BOOL rx);
00535 void Main();
00536 private:
00537 H323Channel & channel;
00538 BOOL receiver;
00539 };
00540
00541
00542 #define new PNEW
00543
00544
00545 #if PTRACING
00546
00547 ostream & operator<<(ostream & out, H323Channel::Directions dir)
00548 {
00549 static const char * const DirNames[H323Channel::NumDirections] = {
00550 "IsBidirectional", "IsTransmitter", "IsReceiver"
00551 };
00552
00553 if (dir < H323Channel::NumDirections && DirNames[dir] != NULL)
00554 out << DirNames[dir];
00555 else
00556 out << "Direction<" << (unsigned)dir << '>';
00557
00558 return out;
00559 }
00560
00561 #endif
00562
00563
00565
00566 H323LogicalChannelThread::H323LogicalChannelThread(H323EndPoint & endpoint,
00567 H323Channel & c,
00568 BOOL rx)
00569 : PThread(endpoint.GetChannelThreadStackSize(),
00570 NoAutoDeleteThread,
00571 endpoint.GetChannelThreadPriority(),
00572 rx ? "LogChanRx:%0x" : "LogChanTx:%0x"),
00573 channel(c)
00574 {
00575 PTRACE(4, "LogChan\tStarting logical channel thread " << this);
00576 receiver = rx;
00577 Resume();
00578 }
00579
00580
00581 void H323LogicalChannelThread::Main()
00582 {
00583 PTRACE(4, "LogChan\tStarted logical channel thread " << this);
00584 if (receiver)
00585 channel.Receive();
00586 else
00587 channel.Transmit();
00588
00589 #ifdef _WIN32_WCE
00590 Sleep(0);
00591 #endif
00592 }
00593
00594
00596
00597 H323ChannelNumber::H323ChannelNumber(unsigned num, BOOL fromRem)
00598 {
00599 PAssert(num < 0x10000, PInvalidParameter);
00600 number = num;
00601 fromRemote = fromRem;
00602 }
00603
00604
00605 PObject * H323ChannelNumber::Clone() const
00606 {
00607 return new H323ChannelNumber(number, fromRemote);
00608 }
00609
00610
00611 PINDEX H323ChannelNumber::HashFunction() const
00612 {
00613 PINDEX hash = (number%17) << 1;
00614 if (fromRemote)
00615 hash++;
00616 return hash;
00617 }
00618
00619
00620 void H323ChannelNumber::PrintOn(ostream & strm) const
00621 {
00622 strm << (fromRemote ? 'R' : 'T') << '-' << number;
00623 }
00624
00625
00626 PObject::Comparison H323ChannelNumber::Compare(const PObject & obj) const
00627 {
00628 #ifndef PASN_LEANANDMEAN
00629 PAssert(PIsDescendant(this, H323ChannelNumber), PInvalidCast);
00630 #endif
00631 const H323ChannelNumber & other = (const H323ChannelNumber &)obj;
00632 if (number < other.number)
00633 return LessThan;
00634 if (number > other.number)
00635 return GreaterThan;
00636 if (fromRemote && !other.fromRemote)
00637 return LessThan;
00638 if (!fromRemote && other.fromRemote)
00639 return GreaterThan;
00640 return EqualTo;
00641 }
00642
00643
00644 H323ChannelNumber & H323ChannelNumber::operator++(int)
00645 {
00646 number++;
00647 return *this;
00648 }
00649
00650
00652
00653 H323Channel::H323Channel(H323Connection & conn, const H323Capability & cap)
00654 : endpoint(conn.GetEndPoint()),
00655 connection(conn)
00656 {
00657 capability = (H323Capability *)cap.Clone();
00658 codec = NULL;
00659 bandwidthUsed = 0;
00660 receiveThread = NULL;
00661 transmitThread = NULL;
00662 terminating = FALSE;
00663 opened = FALSE;
00664 paused = FALSE;
00665 }
00666
00667
00668 H323Channel::~H323Channel()
00669 {
00670 connection.UseBandwidth(bandwidthUsed, TRUE);
00671
00672 delete codec;
00673 delete capability;
00674 }
00675
00676
00677 void H323Channel::PrintOn(ostream & strm) const
00678 {
00679 strm << number;
00680 }
00681
00682
00683 unsigned H323Channel::GetSessionID() const
00684 {
00685 return 0;
00686 }
00687
00688
00689 void H323Channel::CleanUpOnTermination()
00690 {
00691 if (!opened || terminating)
00692 return;
00693
00694 PTRACE(3, "LogChan\tCleaning up " << number);
00695
00696 terminating = TRUE;
00697
00698
00699
00700 if (codec != NULL)
00701 codec->Close();
00702
00703
00704 if (receiveThread != NULL) {
00705 PTRACE(4, "LogChan\tAwaiting termination of " << receiveThread << ' ' << receiveThread->GetThreadName());
00706 PAssert(receiveThread->WaitForTermination(10000), "Receive media thread did not terminate");
00707 delete receiveThread;
00708 receiveThread = NULL;
00709 }
00710
00711
00712 if (transmitThread != NULL) {
00713 PTRACE(4, "LogChan\tAwaiting termination of " << transmitThread << ' ' << transmitThread->GetThreadName());
00714 PAssert(transmitThread->WaitForTermination(10000), "Transmit media thread did not terminate");
00715 delete transmitThread;
00716 transmitThread = NULL;
00717 }
00718
00719
00720 connection.OnClosedLogicalChannel(*this);
00721
00722 PTRACE(3, "LogChan\tCleaned up " << number);
00723 }
00724
00725
00726 BOOL H323Channel::IsRunning() const
00727 {
00728 if (receiveThread != NULL && !receiveThread ->IsTerminated())
00729 return TRUE;
00730
00731 if (transmitThread != NULL && !transmitThread->IsTerminated())
00732 return TRUE;
00733
00734 return FALSE;
00735 }
00736
00737
00738 BOOL H323Channel::OnReceivedPDU(const H245_OpenLogicalChannel & ,
00739 unsigned & )
00740 {
00741 return TRUE;
00742 }
00743
00744
00745 BOOL H323Channel::OnReceivedAckPDU(const H245_OpenLogicalChannelAck & )
00746 {
00747 return TRUE;
00748 }
00749
00750
00751 void H323Channel::OnSendOpenAck(const H245_OpenLogicalChannel & ,
00752 H245_OpenLogicalChannelAck & ) const
00753 {
00754 }
00755
00756
00757 void H323Channel::OnFlowControl(long bitRateRestriction)
00758 {
00759 if (GetCodec() != NULL)
00760 codec->OnFlowControl(bitRateRestriction);
00761 else
00762 PTRACE(3, "LogChan\tOnFlowControl: " << bitRateRestriction);
00763 }
00764
00765
00766 void H323Channel::OnMiscellaneousCommand(const H245_MiscellaneousCommand_type & type)
00767 {
00768 if (GetCodec() != NULL)
00769 codec->OnMiscellaneousCommand(type);
00770 else
00771 PTRACE(3, "LogChan\tOnMiscellaneousCommand: chan=" << number
00772 << ", type=" << type.GetTagName());
00773 }
00774
00775
00776 void H323Channel::OnMiscellaneousIndication(const H245_MiscellaneousIndication_type & type)
00777 {
00778 if (GetCodec() != NULL)
00779 codec->OnMiscellaneousIndication(type);
00780 else
00781 PTRACE(3, "LogChan\tOnMiscellaneousIndication: chan=" << number
00782 << ", type=" << type.GetTagName());
00783 }
00784
00785
00786 void H323Channel::OnJitterIndication(DWORD PTRACE_PARAM(jitter),
00787 int PTRACE_PARAM(skippedFrameCount),
00788 int PTRACE_PARAM(additionalBuffer))
00789 {
00790 PTRACE(3, "LogChan\tOnJitterIndication:"
00791 " jitter=" << jitter <<
00792 " skippedFrameCount=" << skippedFrameCount <<
00793 " additionalBuffer=" << additionalBuffer);
00794 }
00795
00796
00797 BOOL H323Channel::SetInitialBandwidth()
00798 {
00799 if (GetCodec() == NULL)
00800 return TRUE;
00801
00802 return SetBandwidthUsed(codec->GetMediaFormat().GetBandwidth()/100);
00803 }
00804
00805
00806 BOOL H323Channel::SetBandwidthUsed(unsigned bandwidth)
00807 {
00808 PTRACE(3, "LogChan\tBandwidth requested/used = "
00809 << bandwidth/10 << '.' << bandwidth%10 << '/'
00810 << bandwidthUsed/10 << '.' << bandwidthUsed%10
00811 << " kb/s");
00812 connection.UseBandwidth(bandwidthUsed, TRUE);
00813 bandwidthUsed = 0;
00814
00815 if (!connection.UseBandwidth(bandwidth, FALSE))
00816 return FALSE;
00817
00818 bandwidthUsed = bandwidth;
00819 return TRUE;
00820 }
00821
00822
00823 BOOL H323Channel::Open()
00824 {
00825 if (opened)
00826 return TRUE;
00827
00828
00829
00830 if (!connection.OnStartLogicalChannel(*this)) {
00831 PTRACE(1, "LogChan\tOnStartLogicalChannel failed");
00832 return FALSE;
00833 }
00834
00835 opened = TRUE;
00836 return TRUE;
00837 }
00838
00839
00840 H323Codec * H323Channel::GetCodec() const
00841 {
00842 if (codec == NULL) {
00843 ((H323Channel*)this)->codec = capability->CreateCodec(
00844 GetDirection() == IsReceiver ? H323Codec::Decoder : H323Codec::Encoder);
00845 #ifdef H323_AUDIO_CODECS
00846 if (codec && PIsDescendant(codec, H323AudioCodec))
00847 ((H323AudioCodec*)codec)->SetSilenceDetectionMode(endpoint.GetSilenceDetectionMode());
00848 #endif
00849 }
00850
00851 return codec;
00852 }
00853
00854
00855 void H323Channel::SendMiscCommand(unsigned command)
00856 {
00857 connection.SendLogicalChannelMiscCommand(*this, command);
00858 }
00859
00860
00862
00863 H323UnidirectionalChannel::H323UnidirectionalChannel(H323Connection & conn,
00864 const H323Capability & cap,
00865 Directions direction)
00866 : H323Channel(conn, cap),
00867 receiver(direction == IsReceiver)
00868 {
00869 }
00870
00871
00872 H323Channel::Directions H323UnidirectionalChannel::GetDirection() const
00873 {
00874 return receiver ? IsReceiver : IsTransmitter;
00875 }
00876
00877
00878 BOOL H323UnidirectionalChannel::Start()
00879 {
00880 if (!Open())
00881 return FALSE;
00882
00883 PThread * thread = new H323LogicalChannelThread(endpoint, *this, receiver);
00884
00885 if (receiver)
00886 receiveThread = thread;
00887 else
00888 transmitThread = thread;
00889 return TRUE;
00890 }
00891
00892
00894
00895 H323BidirectionalChannel::H323BidirectionalChannel(H323Connection & conn,
00896 const H323Capability & cap)
00897 : H323Channel(conn, cap)
00898 {
00899 }
00900
00901
00902 H323Channel::Directions H323BidirectionalChannel::GetDirection() const
00903 {
00904 return IsBidirectional;
00905 }
00906
00907
00908 BOOL H323BidirectionalChannel::Start()
00909 {
00910 receiveThread = new H323LogicalChannelThread(endpoint, *this, TRUE);
00911 transmitThread = new H323LogicalChannelThread(endpoint, *this, FALSE);
00912 return TRUE;
00913 }
00914
00915
00917
00918 H323_RealTimeChannel::H323_RealTimeChannel(H323Connection & connection,
00919 const H323Capability & capability,
00920 Directions direction)
00921 : H323UnidirectionalChannel(connection, capability, direction)
00922 {
00923 rtpPayloadType = RTP_DataFrame::IllegalPayloadType;
00924 }
00925
00926
00927 BOOL H323_RealTimeChannel::OnSendingPDU(H245_OpenLogicalChannel & open) const
00928 {
00929 PTRACE(3, "H323RTP\tOnSendingPDU");
00930
00931 open.m_forwardLogicalChannelNumber = (unsigned)number;
00932
00933 if (open.HasOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters)) {
00934 open.m_reverseLogicalChannelParameters.IncludeOptionalField(
00935 H245_OpenLogicalChannel_reverseLogicalChannelParameters::e_multiplexParameters);
00936
00937 open.m_reverseLogicalChannelParameters.m_multiplexParameters.SetTag(
00938 H245_OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters
00939 ::e_h2250LogicalChannelParameters);
00940
00941 if (connection.isSameNAT() && OnSendingAltPDU(open.m_genericInformation))
00942 open.IncludeOptionalField(H245_OpenLogicalChannel::e_genericInformation);
00943
00944 return OnSendingPDU(open.m_reverseLogicalChannelParameters.m_multiplexParameters);
00945 }
00946 else {
00947
00948 open.m_forwardLogicalChannelParameters.m_multiplexParameters.SetTag(
00949 H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters
00950 ::e_h2250LogicalChannelParameters);
00951
00952 if (connection.isSameNAT() && OnSendingAltPDU(open.m_genericInformation))
00953 open.IncludeOptionalField(H245_OpenLogicalChannel::e_genericInformation);
00954
00955 return OnSendingPDU(open.m_forwardLogicalChannelParameters.m_multiplexParameters);
00956 }
00957 }
00958
00959
00960 void H323_RealTimeChannel::OnSendOpenAck(const H245_OpenLogicalChannel & open,
00961 H245_OpenLogicalChannelAck & ack) const
00962 {
00963 PTRACE(3, "H323RTP\tOnSendOpenAck");
00964
00965
00966 ack.IncludeOptionalField(H245_OpenLogicalChannelAck::e_forwardMultiplexAckParameters);
00967
00968
00969 ack.m_forwardMultiplexAckParameters.SetTag(
00970 H245_OpenLogicalChannelAck_forwardMultiplexAckParameters::e_h2250LogicalChannelAckParameters);
00971
00972
00973 H245_H2250LogicalChannelAckParameters & param = ack.m_forwardMultiplexAckParameters;
00974
00975
00976 param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_sessionID);
00977 const H245_H2250LogicalChannelParameters & openparam =
00978 open.m_forwardLogicalChannelParameters.m_multiplexParameters;
00979 unsigned sessionID = openparam.m_sessionID;
00980 param.m_sessionID = sessionID;
00981
00982 if (connection.isSameNAT()) {
00983 ack.IncludeOptionalField(H245_OpenLogicalChannelAck::e_genericInformation);
00984 OnSendOpenAckAlt(ack.m_genericInformation);
00985 }
00986
00987 OnSendOpenAck(param);
00988
00989 PTRACE(2, "H323RTP\tSending open logical channel ACK: sessionID=" << sessionID);
00990 }
00991
00992
00993 BOOL H323_RealTimeChannel::OnReceivedPDU(const H245_OpenLogicalChannel & open,
00994 unsigned & errorCode)
00995 {
00996 if (receiver)
00997 number = H323ChannelNumber(open.m_forwardLogicalChannelNumber, TRUE);
00998
00999 PTRACE(3, "H323RTP\tOnReceivedPDU for channel: " << number);
01000
01001 unsigned prevTxFrames = capability->GetTxFramesInPacket();
01002 unsigned prevRxFrames = capability->GetRxFramesInPacket();
01003 PString prevFormat = capability->GetFormatName();
01004
01005 BOOL reverse = open.HasOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters);
01006 const H245_DataType & dataType = reverse ? open.m_reverseLogicalChannelParameters.m_dataType
01007 : open.m_forwardLogicalChannelParameters.m_dataType;
01008
01009 if (!capability->OnReceivedPDU(dataType, receiver)) {
01010 PTRACE(1, "H323RTP\tData type not supported");
01011 errorCode = H245_OpenLogicalChannelReject_cause::e_dataTypeNotSupported;
01012 return FALSE;
01013 }
01014
01015 if (open.HasOptionalField(H245_OpenLogicalChannel::e_genericInformation))
01016 OnReceivedAltPDU(open.m_genericInformation);
01017
01018
01019
01020
01021 if (codec != NULL &&
01022 (prevTxFrames != capability->GetTxFramesInPacket() ||
01023 prevRxFrames != capability->GetRxFramesInPacket() ||
01024 prevFormat != capability->GetFormatName())) {
01025 delete codec;
01026 codec = NULL;
01027 }
01028
01029 if (reverse) {
01030 if (open.m_reverseLogicalChannelParameters.m_multiplexParameters.GetTag() ==
01031 H245_OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters::e_h2250LogicalChannelParameters)
01032 return OnReceivedPDU(open.m_reverseLogicalChannelParameters.m_multiplexParameters, errorCode);
01033 }
01034 else {
01035 if (open.m_forwardLogicalChannelParameters.m_multiplexParameters.GetTag() ==
01036 H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters::e_h2250LogicalChannelParameters)
01037 return OnReceivedPDU(open.m_forwardLogicalChannelParameters.m_multiplexParameters, errorCode);
01038 }
01039
01040 PTRACE(1, "H323RTP\tOnly H.225.0 multiplex supported");
01041 errorCode = H245_OpenLogicalChannelReject_cause::e_unsuitableReverseParameters;
01042 return FALSE;
01043 }
01044
01045
01046 BOOL H323_RealTimeChannel::OnReceivedAckPDU(const H245_OpenLogicalChannelAck & ack)
01047 {
01048 PTRACE(3, "H323RTP\tOnReceiveOpenAck");
01049
01050 if (!ack.HasOptionalField(H245_OpenLogicalChannelAck::e_forwardMultiplexAckParameters)) {
01051 PTRACE(1, "H323RTP\tNo forwardMultiplexAckParameters");
01052 return FALSE;
01053 }
01054
01055 if (ack.m_forwardMultiplexAckParameters.GetTag() !=
01056 H245_OpenLogicalChannelAck_forwardMultiplexAckParameters::e_h2250LogicalChannelAckParameters) {
01057 PTRACE(1, "H323RTP\tOnly H.225.0 multiplex supported");
01058 return FALSE;
01059 }
01060
01061 if (ack.HasOptionalField(H245_OpenLogicalChannel::e_genericInformation))
01062 OnReceivedAckAltPDU(ack.m_genericInformation);
01063
01064 return OnReceivedAckPDU(ack.m_forwardMultiplexAckParameters);
01065 }
01066
01067
01068 RTP_DataFrame::PayloadTypes H323_RealTimeChannel::GetRTPPayloadType() const
01069 {
01070 RTP_DataFrame::PayloadTypes pt = rtpPayloadType;
01071
01072 if (pt == RTP_DataFrame::IllegalPayloadType) {
01073 pt = capability->GetPayloadType();
01074 if (pt == RTP_DataFrame::IllegalPayloadType) {
01075 PAssertNULL(codec);
01076 pt = codec->GetMediaFormat().GetPayloadType();
01077 }
01078 }
01079
01080 return pt;
01081 }
01082
01083
01084 BOOL H323_RealTimeChannel::SetDynamicRTPPayloadType(int newType)
01085 {
01086 PTRACE(1, "H323RTP\tSetting dynamic RTP payload type: " << newType);
01087
01088
01089 if (newType == -1)
01090 return TRUE;
01091
01092
01093 if (newType < RTP_DataFrame::DynamicBase || newType > RTP_DataFrame::MaxPayloadType)
01094 return FALSE;
01095
01096
01097 if (rtpPayloadType < RTP_DataFrame::DynamicBase)
01098 return FALSE;
01099
01100 rtpPayloadType = (RTP_DataFrame::PayloadTypes)newType;
01101 PTRACE(3, "H323RTP\tSetting dynamic payload type to " << rtpPayloadType);
01102 return TRUE;
01103 }
01104
01105
01107
01108 H323_RTPChannel::H323_RTPChannel(H323Connection & conn,
01109 const H323Capability & cap,
01110 Directions direction,
01111 RTP_Session & r)
01112 : H323_RealTimeChannel(conn, cap, direction),
01113 rtpSession(r),
01114 rtpCallbacks(*(H323_RTP_Session *)r.GetUserData())
01115 {
01116 PTRACE(3, "H323RTP\t" << (receiver ? "Receiver" : "Transmitter")
01117 << " created using session " << GetSessionID());
01118 }
01119
01120
01121 H323_RTPChannel::~H323_RTPChannel()
01122 {
01123
01124
01125 connection.ReleaseSession(GetSessionID());
01126 }
01127
01128
01129 void H323_RTPChannel::CleanUpOnTermination()
01130 {
01131 if (terminating)
01132 return;
01133
01134 PTRACE(3, "H323RTP\tCleaning up RTP " << number);
01135
01136
01137
01138 if ((receiver ? receiveThread : transmitThread) != NULL)
01139 rtpSession.Close(receiver);
01140
01141 H323Channel::CleanUpOnTermination();
01142 }
01143
01144
01145 unsigned H323_RTPChannel::GetSessionID() const
01146 {
01147 return rtpSession.GetSessionID();
01148 }
01149
01150
01151 BOOL H323_RTPChannel::Open()
01152 {
01153 if (opened)
01154 return TRUE;
01155
01156 if (GetCodec() == NULL) {
01157 PTRACE(1, "LogChan\t" << (GetDirection() == IsReceiver ? "Receive" : "Transmit")
01158 << " thread aborted (could not create codec)");
01159 return FALSE;
01160 }
01161
01162 if (!codec->GetMediaFormat().IsValid()) {
01163 PTRACE(1, "LogChan\t" << (GetDirection() == IsReceiver ? "Receive" : "Transmit")
01164 << " thread aborted (invalid media format)");
01165 return FALSE;
01166 }
01167
01168 codec->AttachLogicalChannel((H323Channel*)this);
01169
01170
01171 if (!codec->Open(connection)) {
01172 PTRACE(1, "LogChan\t" << (GetDirection() == IsReceiver ? "Receive" : "Transmit")
01173 << " thread aborted (open fail) for "<< *capability);
01174 return FALSE;
01175 }
01176
01177
01178
01179 if (!connection.OnStartLogicalChannel(*this)) {
01180 PTRACE(1, "LogChan\t" << (GetDirection() == IsReceiver ? "Receive" : "Transmit")
01181 << " thread aborted (OnStartLogicalChannel fail)");
01182 return FALSE;
01183 }
01184
01185 PTRACE(3, "LogChan\tOpened using capability " << *capability);
01186
01187 opened = TRUE;
01188
01189 return TRUE;
01190 }
01191
01192
01193 BOOL H323_RTPChannel::OnSendingPDU(H245_H2250LogicalChannelParameters & param) const
01194 {
01195 return rtpCallbacks.OnSendingPDU(*this, param);
01196 }
01197
01198 BOOL H323_RTPChannel::OnSendingAltPDU(H245_ArrayOf_GenericInformation & alternate) const
01199 {
01200 return rtpCallbacks.OnSendingAltPDU(*this, alternate);
01201 }
01202
01203 void H323_RTPChannel::OnSendOpenAck(H245_H2250LogicalChannelAckParameters & param) const
01204 {
01205 rtpCallbacks.OnSendingAckPDU(*this, param);
01206 }
01207
01208 void H323_RTPChannel::OnSendOpenAckAlt(H245_ArrayOf_GenericInformation & alternate) const
01209 {
01210 rtpCallbacks.OnSendOpenAckAlt(*this, alternate);
01211 }
01212
01213 BOOL H323_RTPChannel::OnReceivedPDU(const H245_H2250LogicalChannelParameters & param,
01214 unsigned & errorCode)
01215 {
01216 return rtpCallbacks.OnReceivedPDU(*this, param, errorCode);
01217 }
01218
01219 BOOL H323_RTPChannel::OnReceivedAltPDU(const H245_ArrayOf_GenericInformation & alternate)
01220 {
01221 return rtpCallbacks.OnReceivedAltPDU(*this, alternate);
01222 }
01223
01224
01225 BOOL H323_RTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param)
01226 {
01227 return rtpCallbacks.OnReceivedAckPDU(*this, param);
01228 }
01229
01230 BOOL H323_RTPChannel::OnReceivedAckAltPDU(const H245_ArrayOf_GenericInformation & alternate)
01231 {
01232 return rtpCallbacks.OnReceivedAckAltPDU(*this, alternate);
01233 }
01234
01235
01236 #if PTRACING
01237 class CodecReadAnalyser
01238 {
01239 enum { MaxSamples = 1000 };
01240 public:
01241 CodecReadAnalyser() { count = 0; }
01242 void AddSample(DWORD timestamp)
01243 {
01244 if (count < MaxSamples) {
01245 tick[count] = PTimer::Tick();
01246 rtp[count] = timestamp;
01247 count++;
01248 }
01249 }
01250 friend ostream & operator<<(ostream & strm, const CodecReadAnalyser & analysis)
01251 {
01252 PTimeInterval minimum = PMaxTimeInterval;
01253 PTimeInterval maximum;
01254 for (PINDEX i = 1; i < analysis.count; i++) {
01255 PTimeInterval delta = analysis.tick[i] - analysis.tick[i-1];
01256 strm << setw(6) << analysis.rtp[i] << ' '
01257 << setw(6) << (analysis.tick[i] - analysis.tick[0]) << ' '
01258 << setw(6) << delta
01259 << '\n';
01260 if (delta > maximum)
01261 maximum = delta;
01262 if (delta < minimum)
01263 minimum = delta;
01264 }
01265 strm << "Maximum delta time: " << maximum << "\n"
01266 "Minimum delta time: " << minimum << '\n';
01267 return strm;
01268 }
01269 private:
01270 PTimeInterval tick[MaxSamples];
01271 DWORD rtp[MaxSamples];
01272 PINDEX count;
01273 };
01274 #endif
01275
01276
01277 void H323_RTPChannel::Transmit()
01278 {
01279 if (terminating) {
01280 PTRACE(3, "H323RTP\tTransmit thread terminated on start up");
01281 return;
01282 }
01283
01284 const OpalMediaFormat & mediaFormat = codec->GetMediaFormat();
01285
01286
01287 BOOL isAudio = mediaFormat.NeedsJitterBuffer();
01288 unsigned framesInPacket = capability->GetTxFramesInPacket();
01289 unsigned maxFrameSize = mediaFormat.GetFrameSize();
01290 if (maxFrameSize == 0)
01291 maxFrameSize = isAudio ? 8 : 2000;
01292 RTP_DataFrame frame(framesInPacket*maxFrameSize);
01293
01294 rtpPayloadType = GetRTPPayloadType();
01295 if (rtpPayloadType == RTP_DataFrame::IllegalPayloadType) {
01296 PTRACE(1, "H323RTP\tReceive " << mediaFormat << " thread ended (illegal payload type)");
01297 return;
01298 }
01299 frame.SetPayloadType(rtpPayloadType);
01300
01301 PTRACE(2, "H323RTP\tTransmit " << mediaFormat << " thread started:"
01302 " rate=" << codec->GetFrameRate() <<
01303 " time=" << (codec->GetFrameRate()/(mediaFormat.GetTimeUnits() > 0 ? mediaFormat.GetTimeUnits() : 1)) << "ms" <<
01304 " size=" << framesInPacket << '*' << maxFrameSize << '='
01305 << (framesInPacket*maxFrameSize) );
01306
01307
01308 BOOL silent = TRUE;
01309 unsigned length;
01310 unsigned frameOffset = 0;
01311 unsigned frameCount = 0;
01312 DWORD rtpTimestamp = 0;
01313 frame.SetPayloadSize(0);
01314
01315 #if PTRACING
01316 DWORD lastDisplayedTimestamp = 0;
01317 CodecReadAnalyser * codecReadAnalysis = NULL;
01318 if (PTrace::GetLevel() >= 5)
01319 codecReadAnalysis = new CodecReadAnalyser;
01320 #endif
01321
01322
01323
01324
01325
01326
01327 while (codec->Read(frame.GetPayloadPtr()+frameOffset, length, frame)) {
01328
01329 rtpTimestamp += codec->GetFrameRate();
01330
01331 #if PTRACING
01332 if (rtpTimestamp - lastDisplayedTimestamp > RTP_TRACE_DISPLAY_RATE) {
01333 PTRACE(3, "H323RTP\tTransmitter sent timestamp " << rtpTimestamp);
01334 lastDisplayedTimestamp = rtpTimestamp;
01335 }
01336
01337 if (codecReadAnalysis != NULL)
01338 codecReadAnalysis->AddSample(rtpTimestamp);
01339 #endif
01340
01341 if (paused)
01342 length = 0;
01343
01344
01345 if (isAudio) {
01346
01347 if (silent && length > 0) {
01348 silent = FALSE;
01349 frame.SetMarker(TRUE);
01350 PTRACE(3, "H323RTP\tTransmit start of talk burst: " << rtpTimestamp);
01351 }
01352
01353 else if (!silent && length == 0) {
01354 silent = TRUE;
01355
01356 if (frameOffset > 0)
01357 frameCount = framesInPacket;
01358 PTRACE(3, "H323RTP\tTransmit end of talk burst: " << rtpTimestamp);
01359 }
01360 }
01361
01362
01363 if (length == 0)
01364 frame.SetTimestamp(rtpTimestamp);
01365 else {
01366 silenceStartTick = PTimer::Tick();
01367
01368
01369 if (frameOffset == 0)
01370 frame.SetTimestamp(rtpTimestamp);
01371 frameOffset += length;
01372
01373
01374 if (rtpPayloadType == RTP_DataFrame::G729 && length == 2) {
01375
01376
01377
01378 frameCount = framesInPacket;
01379 }
01380 else {
01381
01382
01383
01384
01385 frameCount += (length + maxFrameSize - 1)/maxFrameSize;
01386 }
01387 }
01388
01389 BOOL sendPacket = FALSE;
01390
01391
01392 if (frameCount >= framesInPacket) {
01393
01394 frame.SetPayloadSize(frameOffset);
01395 frame.SetPayloadType(rtpPayloadType);
01396
01397 frameOffset = 0;
01398 frameCount = 0;
01399
01400 sendPacket = TRUE;
01401 }
01402
01403 filterMutex.Wait();
01404 for (PINDEX i = 0; i < filters.GetSize(); i++)
01405 filters[i](frame, (INT)&sendPacket);
01406 filterMutex.Signal();
01407
01408 if (sendPacket || (silent && frame.GetPayloadSize() > 0)) {
01409
01410 if (!rtpSession.WriteData(frame))
01411 break;
01412
01413
01414 if (isAudio)
01415 frame.SetMarker(FALSE);
01416
01417 frame.SetPayloadSize(0);
01418 frameOffset = 0;
01419 frameCount = 0;
01420 }
01421
01422 if (terminating)
01423 break;
01424 }
01425
01426 #if PTRACING
01427 PTRACE_IF(5, codecReadAnalysis != NULL, "Codec read timing:\n" << *codecReadAnalysis);
01428 delete codecReadAnalysis;
01429 #endif
01430
01431 if (!terminating)
01432 connection.CloseLogicalChannelNumber(number);
01433
01434 PTRACE(2, "H323RTP\tTransmit " << mediaFormat << " thread ended");
01435 }
01436
01437
01438 void H323_RTPChannel::Receive()
01439 {
01440 if (terminating) {
01441 PTRACE(3, "H323RTP\tReceive thread terminated on start up");
01442 return;
01443 }
01444
01445 const OpalMediaFormat & mediaFormat = codec->GetMediaFormat();
01446
01447 PTRACE(2, "H323RTP\tReceive " << mediaFormat << " thread started.");
01448
01449
01450 if (mediaFormat.NeedsJitterBuffer())
01451 rtpSession.SetJitterBufferSize(connection.GetMinAudioJitterDelay()*mediaFormat.GetTimeUnits(),
01452 connection.GetMaxAudioJitterDelay()*mediaFormat.GetTimeUnits(),
01453 endpoint.GetJitterThreadStackSize());
01454
01455
01456 DWORD codecFrameRate = codec->GetFrameRate();
01457 DWORD rtpTimestamp = 0;
01458 #if PTRACING
01459 DWORD lastDisplayedTimestamp = 0;
01460 #endif
01461
01462
01463 int consecutiveMismatches = 0;
01464
01465 rtpPayloadType = GetRTPPayloadType();
01466 if (rtpPayloadType == RTP_DataFrame::IllegalPayloadType) {
01467 PTRACE(1, "H323RTP\tTransmit " << mediaFormat << " thread ended (illegal payload type)");
01468 return;
01469 }
01470
01471 BOOL allowRtpPayloadChange = codec->GetMediaFormat().GetDefaultSessionID() == OpalMediaFormat::DefaultAudioSessionID;
01472
01473 RTP_DataFrame frame;
01474 while (rtpSession.ReadBufferedData(rtpTimestamp, frame)) {
01475
01476 filterMutex.Wait();
01477 for (PINDEX i = 0; i < filters.GetSize(); i++)
01478 filters[i](frame, 0);
01479 filterMutex.Signal();
01480
01481 int size = frame.GetPayloadSize();
01482 rtpTimestamp = frame.GetTimestamp();
01483
01484 #if PTRACING
01485 if (rtpTimestamp - lastDisplayedTimestamp > RTP_TRACE_DISPLAY_RATE) {
01486 PTRACE(3, "H323RTP\tReceiver written timestamp " << rtpTimestamp);
01487 lastDisplayedTimestamp = rtpTimestamp;
01488 }
01489 #endif
01490
01491 unsigned written;
01492 BOOL ok = TRUE;
01493 if (size == 0) {
01494 ok = codec->Write(NULL, 0, frame, written);
01495 rtpTimestamp += codecFrameRate;
01496 } else {
01497 silenceStartTick = PTimer::Tick();
01498
01499 BOOL isCodecPacket = TRUE;
01500
01501 if (frame.GetPayloadType() == rtpPayloadType) {
01502 PTRACE_IF(2, consecutiveMismatches > 0,
01503 "H323RTP\tPayload type matched again " << rtpPayloadType);
01504 consecutiveMismatches = 0;
01505 }
01506 else {
01507 consecutiveMismatches++;
01508 if (allowRtpPayloadChange && consecutiveMismatches >= MAX_PAYLOAD_TYPE_MISMATCHES) {
01509 rtpPayloadType = frame.GetPayloadType();
01510 consecutiveMismatches = 0;
01511 PTRACE(1, "H323RTP\tResetting expected payload type to " << rtpPayloadType);
01512 }
01513 PTRACE_IF(2, consecutiveMismatches < MAX_PAYLOAD_TYPE_MISMATCHES, "H323RTP\tPayload type mismatch: expected "
01514 << rtpPayloadType << ", got " << frame.GetPayloadType()
01515 << ". Ignoring packet.");
01516 }
01517
01518 if (isCodecPacket && consecutiveMismatches == 0) {
01519 const BYTE * ptr = frame.GetPayloadPtr();
01520 while (ok && size > 0) {
01521
01522
01523
01524
01525
01526
01527 ok = codec->Write(ptr, paused ? 0 : size, frame, written);
01528 rtpTimestamp += codecFrameRate;
01529 size -= written != 0 ? written : size;
01530 ptr += written;
01531 }
01532 PTRACE_IF(1, size < 0, "H323RTP\tPayload size too small, short " << -size << " bytes.");
01533 }
01534 }
01535
01536 if (terminating)
01537 break;
01538
01539 if (!ok) {
01540 connection.CloseLogicalChannelNumber(number);
01541 break;
01542 }
01543 }
01544
01545 PTRACE(2, "H323RTP\tReceive " << mediaFormat << " thread ended");
01546 }
01547
01548
01549 void H323_RTPChannel::AddFilter(const PNotifier & filterFunction)
01550 {
01551 filterMutex.Wait();
01552 filters.Append(new PNotifier(filterFunction));
01553 filterMutex.Signal();
01554 }
01555
01556
01557 void H323_RTPChannel::RemoveFilter(const PNotifier & filterFunction)
01558 {
01559 filterMutex.Wait();
01560 PINDEX idx = filters.GetValuesIndex(filterFunction);
01561 if (idx != P_MAX_INDEX)
01562 filters.RemoveAt(idx);
01563 filterMutex.Signal();
01564 }
01565
01566
01567 PTimeInterval H323_RTPChannel::GetSilenceDuration() const
01568 {
01569 if (silenceStartTick == 0)
01570 return silenceStartTick;
01571
01572 return PTimer::Tick() - silenceStartTick;
01573 }
01574
01575
01577
01578 H323_ExternalRTPChannel::H323_ExternalRTPChannel(H323Connection & connection,
01579 const H323Capability & capability,
01580 Directions direction,
01581 unsigned id)
01582 : H323_RealTimeChannel(connection, capability, direction)
01583 {
01584 sessionID = id;
01585 isRunning = FALSE;
01586 }
01587
01588
01589 H323_ExternalRTPChannel::H323_ExternalRTPChannel(H323Connection & connection,
01590 const H323Capability & capability,
01591 Directions direction,
01592 unsigned id,
01593 const H323TransportAddress & data,
01594 const H323TransportAddress & control)
01595 : H323_RealTimeChannel(connection, capability, direction),
01596 externalMediaAddress(data),
01597 externalMediaControlAddress(control)
01598 {
01599 sessionID = id;
01600 isRunning = FALSE;
01601 }
01602
01603
01604 H323_ExternalRTPChannel::H323_ExternalRTPChannel(H323Connection & connection,
01605 const H323Capability & capability,
01606 Directions direction,
01607 unsigned id,
01608 const PIPSocket::Address & ip,
01609 WORD dataPort)
01610 : H323_RealTimeChannel(connection, capability, direction),
01611 externalMediaAddress(ip, dataPort),
01612 externalMediaControlAddress(ip, (WORD)(dataPort+1))
01613 {
01614 sessionID = id;
01615 isRunning = FALSE;
01616 }
01617
01618
01619 unsigned H323_ExternalRTPChannel::GetSessionID() const
01620 {
01621 return sessionID;
01622 }
01623
01624
01625 BOOL H323_ExternalRTPChannel::Start()
01626 {
01627 isRunning = TRUE;
01628 return Open();
01629 }
01630
01631
01632 BOOL H323_ExternalRTPChannel::IsRunning() const
01633 {
01634 return opened && isRunning;
01635 }
01636
01637
01638 void H323_ExternalRTPChannel::Receive()
01639 {
01640
01641 }
01642
01643
01644 void H323_ExternalRTPChannel::Transmit()
01645 {
01646
01647 }
01648
01649
01650 BOOL H323_ExternalRTPChannel::OnSendingPDU(H245_H2250LogicalChannelParameters & param) const
01651 {
01652 param.m_sessionID = sessionID;
01653
01654 param.IncludeOptionalField(H245_H2250LogicalChannelParameters::e_mediaGuaranteedDelivery);
01655 param.m_mediaGuaranteedDelivery = FALSE;
01656
01657 param.IncludeOptionalField(H245_H2250LogicalChannelParameters::e_silenceSuppression);
01658 param.m_silenceSuppression = FALSE;
01659
01660
01661 param.IncludeOptionalField(H245_H2250LogicalChannelParameters::e_mediaControlChannel);
01662 externalMediaControlAddress.SetPDU(param.m_mediaControlChannel);
01663
01664 if (receiver) {
01665
01666 param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaChannel);
01667 externalMediaAddress.SetPDU(param.m_mediaChannel);
01668 }
01669
01670 return TRUE;
01671 }
01672
01673
01674 void H323_ExternalRTPChannel::OnSendOpenAck(H245_H2250LogicalChannelAckParameters & param) const
01675 {
01676
01677 param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaControlChannel);
01678 externalMediaControlAddress.SetPDU(param.m_mediaControlChannel);
01679
01680
01681 param.IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaChannel);
01682 externalMediaAddress.SetPDU(param.m_mediaChannel);
01683 }
01684
01685
01686 BOOL H323_ExternalRTPChannel::OnReceivedPDU(const H245_H2250LogicalChannelParameters & param,
01687 unsigned & errorCode)
01688 {
01689
01690 if (param.m_sessionID != sessionID) {
01691 PTRACE(1, "LogChan\tOpen for invalid session: " << param.m_sessionID);
01692 errorCode = H245_OpenLogicalChannelReject_cause::e_invalidSessionID;
01693 return FALSE;
01694 }
01695
01696 if (!param.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaControlChannel)) {
01697 PTRACE(1, "LogChan\tNo mediaControlChannel specified");
01698 errorCode = H245_OpenLogicalChannelReject_cause::e_unspecified;
01699 return FALSE;
01700 }
01701
01702 remoteMediaControlAddress = param.m_mediaControlChannel;
01703 if (remoteMediaControlAddress.IsEmpty())
01704 return FALSE;
01705
01706 if (param.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaChannel)) {
01707 remoteMediaAddress = param.m_mediaChannel;
01708 if (remoteMediaAddress.IsEmpty())
01709 return FALSE;
01710 }
01711
01712 return TRUE;
01713 }
01714
01715
01716 BOOL H323_ExternalRTPChannel::OnReceivedAckPDU(const H245_H2250LogicalChannelAckParameters & param)
01717 {
01718 if (param.HasOptionalField(H245_H2250LogicalChannelAckParameters::e_sessionID) && (param.m_sessionID != sessionID)) {
01719 PTRACE(1, "LogChan\twarning: Ack for invalid session: " << param.m_sessionID);
01720 }
01721
01722 if (!param.HasOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaControlChannel)) {
01723 PTRACE(1, "LogChan\tNo mediaControlChannel specified");
01724 return FALSE;
01725 }
01726
01727 remoteMediaControlAddress = param.m_mediaControlChannel;
01728 if (remoteMediaControlAddress.IsEmpty())
01729 return FALSE;
01730
01731 if (!param.HasOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaChannel)) {
01732 PTRACE(1, "LogChan\tNo mediaChannel specified");
01733 return FALSE;
01734 }
01735
01736 remoteMediaAddress = param.m_mediaChannel;
01737 if (remoteMediaAddress.IsEmpty())
01738 return FALSE;
01739
01740 return TRUE;
01741 }
01742
01743
01744 void H323_ExternalRTPChannel::SetExternalAddress(const H323TransportAddress & data,
01745 const H323TransportAddress & control)
01746 {
01747 externalMediaAddress = data;
01748 externalMediaControlAddress = control;
01749
01750 if (data.IsEmpty() || control.IsEmpty()) {
01751 PIPSocket::Address ip;
01752 WORD port;
01753 if (data.GetIpAndPort(ip, port))
01754 externalMediaControlAddress = H323TransportAddress(ip, (WORD)(port+1));
01755 else if (control.GetIpAndPort(ip, port))
01756 externalMediaAddress = H323TransportAddress(ip, (WORD)(port-1));
01757 }
01758 }
01759
01760
01761 BOOL H323_ExternalRTPChannel::GetRemoteAddress(PIPSocket::Address & ip,
01762 WORD & dataPort) const
01763 {
01764 if (!remoteMediaControlAddress) {
01765 if (remoteMediaControlAddress.GetIpAndPort(ip, dataPort)) {
01766 dataPort--;
01767 return TRUE;
01768 }
01769 }
01770
01771 if (!remoteMediaAddress)
01772 return remoteMediaAddress.GetIpAndPort(ip, dataPort);
01773
01774 return FALSE;
01775 }
01776
01777
01779
01780 H323DataChannel::H323DataChannel(H323Connection & conn,
01781 const H323Capability & cap,
01782 Directions dir,
01783 unsigned id)
01784 : H323UnidirectionalChannel(conn, cap, dir)
01785 {
01786 sessionID = id;
01787 listener = NULL;
01788 autoDeleteListener = TRUE;
01789 transport = NULL;
01790 autoDeleteTransport = TRUE;
01791 separateReverseChannel = FALSE;
01792 }
01793
01794
01795 H323DataChannel::~H323DataChannel()
01796 {
01797 if (autoDeleteListener)
01798 delete listener;
01799 if (autoDeleteTransport)
01800 delete transport;
01801 }
01802
01803
01804 void H323DataChannel::CleanUpOnTermination()
01805 {
01806 if (terminating)
01807 return;
01808
01809 PTRACE(3, "LogChan\tCleaning up data channel " << number);
01810
01811
01812
01813 if (listener != NULL)
01814 listener->Close();
01815 if (transport != NULL)
01816 transport->Close();
01817
01818 H323UnidirectionalChannel::CleanUpOnTermination();
01819 }
01820
01821
01822 unsigned H323DataChannel::GetSessionID() const
01823 {
01824 return sessionID;
01825 }
01826
01827
01828 BOOL H323DataChannel::OnSendingPDU(H245_OpenLogicalChannel & open) const
01829 {
01830 PTRACE(3, "LogChan\tOnSendingPDU for channel: " << number);
01831
01832 open.m_forwardLogicalChannelNumber = (unsigned)number;
01833
01834 open.m_forwardLogicalChannelParameters.m_multiplexParameters.SetTag(
01835 H245_OpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters
01836 ::e_h2250LogicalChannelParameters);
01837 H245_H2250LogicalChannelParameters & fparam = open.m_forwardLogicalChannelParameters.m_multiplexParameters;
01838 fparam.m_sessionID = GetSessionID();
01839
01840 if (separateReverseChannel)
01841 return TRUE;
01842
01843 open.IncludeOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters);
01844 open.m_reverseLogicalChannelParameters.IncludeOptionalField(
01845 H245_OpenLogicalChannel_reverseLogicalChannelParameters::e_multiplexParameters);
01846 open.m_reverseLogicalChannelParameters.m_multiplexParameters.SetTag(
01847 H245_OpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters
01848 ::e_h2250LogicalChannelParameters);
01849 H245_H2250LogicalChannelParameters & rparam = open.m_reverseLogicalChannelParameters.m_multiplexParameters;
01850 rparam.m_sessionID = GetSessionID();
01851
01852 return capability->OnSendingPDU(open.m_reverseLogicalChannelParameters.m_dataType);
01853 }
01854
01855
01856 void H323DataChannel::OnSendOpenAck(const H245_OpenLogicalChannel & ,
01857 H245_OpenLogicalChannelAck & ack) const
01858 {
01859 if (listener == NULL && transport == NULL) {
01860 PTRACE(2, "LogChan\tOnSendOpenAck without a listener or transport");
01861 return;
01862 }
01863
01864 PTRACE(3, "LogChan\tOnSendOpenAck for channel: " << number);
01865
01866 H245_H2250LogicalChannelAckParameters * param;
01867
01868 if (separateReverseChannel) {
01869 ack.IncludeOptionalField(H245_OpenLogicalChannelAck::e_forwardMultiplexAckParameters);
01870 ack.m_forwardMultiplexAckParameters.SetTag(
01871 H245_OpenLogicalChannelAck_forwardMultiplexAckParameters::e_h2250LogicalChannelAckParameters);
01872 param = (H245_H2250LogicalChannelAckParameters*)&ack.m_forwardMultiplexAckParameters.GetObject();
01873 }
01874 else {
01875 ack.IncludeOptionalField(H245_OpenLogicalChannelAck::e_reverseLogicalChannelParameters);
01876 ack.m_reverseLogicalChannelParameters.m_multiplexParameters.SetTag(
01877 H245_OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters
01878 ::e_h2250LogicalChannelParameters);
01879 param = (H245_H2250LogicalChannelAckParameters*)
01880 &ack.m_reverseLogicalChannelParameters.m_multiplexParameters.GetObject();
01881 }
01882
01883 unsigned session = GetSessionID();
01884 if (session != 0) {
01885 param->IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_sessionID);
01886 param->m_sessionID = GetSessionID();
01887 }
01888
01889 param->IncludeOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaChannel);
01890 if (listener != NULL)
01891 listener->SetUpTransportPDU(param->m_mediaChannel, connection.GetControlChannel());
01892 else
01893 transport->SetUpTransportPDU(param->m_mediaChannel, H323Transport::UseLocalTSAP);
01894 }
01895
01896
01897 BOOL H323DataChannel::OnReceivedPDU(const H245_OpenLogicalChannel & open,
01898 unsigned & errorCode)
01899 {
01900 number = H323ChannelNumber(open.m_forwardLogicalChannelNumber, TRUE);
01901
01902 PTRACE(3, "LogChan\tOnReceivedPDU for data channel: " << number);
01903
01904 if (!CreateListener()) {
01905 PTRACE(1, "LogChan\tCould not create listener");
01906 errorCode = H245_OpenLogicalChannelReject_cause::e_unspecified;
01907 return FALSE;
01908 }
01909
01910 if (separateReverseChannel &&
01911 open.HasOptionalField(H245_OpenLogicalChannel::e_reverseLogicalChannelParameters)) {
01912 errorCode = H245_OpenLogicalChannelReject_cause::e_unsuitableReverseParameters;
01913 PTRACE(2, "LogChan\tOnReceivedPDU has unexpected reverse parameters");
01914 return FALSE;
01915 }
01916
01917 if (!capability->OnReceivedPDU(open.m_forwardLogicalChannelParameters.m_dataType, receiver)) {
01918 PTRACE(1, "H323RTP\tData type not supported");
01919 errorCode = H245_OpenLogicalChannelReject_cause::e_dataTypeNotSupported;
01920 return FALSE;
01921 }
01922
01923 return TRUE;
01924 }
01925
01926
01927 BOOL H323DataChannel::OnReceivedAckPDU(const H245_OpenLogicalChannelAck & ack)
01928 {
01929 PTRACE(3, "LogChan\tOnReceivedAckPDU");
01930
01931 const H245_TransportAddress * address;
01932
01933 if (separateReverseChannel) {
01934 PTRACE(3, "LogChan\tseparateReverseChannels");
01935 if (!ack.HasOptionalField(H245_OpenLogicalChannelAck::e_forwardMultiplexAckParameters)) {
01936 PTRACE(1, "LogChan\tNo forwardMultiplexAckParameters");
01937 return FALSE;
01938 }
01939
01940 if (ack.m_forwardMultiplexAckParameters.GetTag() !=
01941 H245_OpenLogicalChannelAck_forwardMultiplexAckParameters::e_h2250LogicalChannelAckParameters) {
01942 PTRACE(1, "LogChan\tOnly H.225.0 multiplex supported");
01943 return FALSE;
01944 }
01945
01946 const H245_H2250LogicalChannelAckParameters & param = ack.m_forwardMultiplexAckParameters;
01947
01948 if (!param.HasOptionalField(H245_H2250LogicalChannelAckParameters::e_mediaChannel)) {
01949 PTRACE(1, "LogChan\tNo media channel address provided");
01950 return FALSE;
01951 }
01952
01953 address = ¶m.m_mediaChannel;
01954
01955 if (ack.HasOptionalField(H245_OpenLogicalChannelAck::e_reverseLogicalChannelParameters)) {
01956 PTRACE(3, "LogChan\treverseLogicalChannelParameters set");
01957 reverseChannel = H323ChannelNumber(ack.m_reverseLogicalChannelParameters.m_reverseLogicalChannelNumber, TRUE);
01958 }
01959 }
01960 else {
01961 if (!ack.HasOptionalField(H245_OpenLogicalChannelAck::e_reverseLogicalChannelParameters)) {
01962 PTRACE(1, "LogChan\tNo reverseLogicalChannelParameters");
01963 return FALSE;
01964 }
01965
01966 if (ack.m_reverseLogicalChannelParameters.m_multiplexParameters.GetTag() !=
01967 H245_OpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters
01968 ::e_h2250LogicalChannelParameters) {
01969 PTRACE(1, "LogChan\tOnly H.225.0 multiplex supported");
01970 return FALSE;
01971 }
01972
01973 const H245_H2250LogicalChannelParameters & param = ack.m_reverseLogicalChannelParameters.m_multiplexParameters;
01974
01975 if (!param.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaChannel)) {
01976 PTRACE(1, "LogChan\tNo media channel address provided");
01977 return FALSE;
01978 }
01979
01980 address = ¶m.m_mediaChannel;
01981 }
01982
01983 if (!CreateTransport()) {
01984 PTRACE(1, "LogChan\tCould not create transport");
01985 return FALSE;
01986 }
01987
01988 if (!transport->ConnectTo(*address)) {
01989 PTRACE(1, "LogChan\tCould not connect to remote transport address: " << *address);
01990 return FALSE;
01991 }
01992
01993 return TRUE;
01994 }
01995
01996
01997 BOOL H323DataChannel::CreateListener()
01998 {
01999 if (listener == NULL) {
02000 listener = connection.GetControlChannel().GetLocalAddress().CreateCompatibleListener(connection.GetEndPoint());
02001 if (listener == NULL)
02002 return FALSE;
02003
02004 PTRACE(3, "LogChan\tCreated listener for data channel: " << *listener);
02005 }
02006
02007 return listener->Open();
02008 }
02009
02010
02011 BOOL H323DataChannel::CreateTransport()
02012 {
02013 if (transport == NULL) {
02014 transport = connection.GetControlChannel().GetLocalAddress().CreateTransport(connection.GetEndPoint());
02015 if (transport == NULL)
02016 return FALSE;
02017
02018 PTRACE(3, "LogChan\tCreated transport for data channel: " << *transport);
02019 }
02020
02021 return transport != NULL;
02022 }
02023
02024