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 #ifndef __OPAL_H323NEG_H
00165 #define __OPAL_H323NEG_H
00166
00167 #ifdef P_USE_PRAGMA
00168 #pragma interface
00169 #endif
00170
00171
00172 #include <h323/h323pdu.h>
00173 #include <h323/channels.h>
00174
00175
00176 class H323EndPoint;
00177 class H323Connection;
00178
00179
00181
00184 class H245Negotiator : public PObject
00185 {
00186 PCLASSINFO(H245Negotiator, PObject);
00187
00188 public:
00189 H245Negotiator(H323EndPoint & endpoint, H323Connection & connection);
00190
00191 protected:
00192 PDECLARE_NOTIFIER(PTimer, H245Negotiator, HandleTimeout);
00193
00194 H323EndPoint & endpoint;
00195 H323Connection & connection;
00196 PTimer replyTimer;
00197 PMutex mutex;
00198 };
00199
00200
00203 class H245NegMasterSlaveDetermination : public H245Negotiator
00204 {
00205 PCLASSINFO(H245NegMasterSlaveDetermination, H245Negotiator);
00206
00207 public:
00208 H245NegMasterSlaveDetermination(H323EndPoint & endpoint, H323Connection & connection);
00209
00210 BOOL Start(BOOL renegotiate);
00211 void Stop();
00212 BOOL HandleIncoming(const H245_MasterSlaveDetermination & pdu);
00213 BOOL HandleAck(const H245_MasterSlaveDeterminationAck & pdu);
00214 BOOL HandleReject(const H245_MasterSlaveDeterminationReject & pdu);
00215 BOOL HandleRelease(const H245_MasterSlaveDeterminationRelease & pdu);
00216 void HandleTimeout(PTimer &, INT);
00217
00218 BOOL IsMaster() const { return status == e_DeterminedMaster; }
00219 BOOL IsDetermined() const { return state == e_Idle && status != e_Indeterminate; }
00220
00221 protected:
00222 BOOL Restart();
00223
00224 enum States {
00225 e_Idle, e_Outgoing, e_Incoming,
00226 e_NumStates
00227 } state;
00228 #if PTRACING
00229 static const char * const StateNames[e_NumStates];
00230 friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
00231 #endif
00232
00233 DWORD determinationNumber;
00234 unsigned retryCount;
00235
00236 enum MasterSlaveStatus {
00237 e_Indeterminate, e_DeterminedMaster, e_DeterminedSlave,
00238 e_NumStatuses
00239 } status;
00240 #if PTRACING
00241 static const char * const StatusNames[e_NumStatuses];
00242 friend ostream & operator<<(ostream & o , MasterSlaveStatus s) { return o << StatusNames[s]; }
00243 #endif
00244 };
00245
00246
00249 class H245NegTerminalCapabilitySet : public H245Negotiator
00250 {
00251 PCLASSINFO(H245NegTerminalCapabilitySet, H245Negotiator);
00252
00253 public:
00254 H245NegTerminalCapabilitySet(H323EndPoint & endpoint, H323Connection & connection);
00255
00256 BOOL Start(BOOL renegotiate, BOOL empty = FALSE);
00257 void Stop();
00258 BOOL HandleIncoming(const H245_TerminalCapabilitySet & pdu);
00259 BOOL HandleAck(const H245_TerminalCapabilitySetAck & pdu);
00260 BOOL HandleReject(const H245_TerminalCapabilitySetReject & pdu);
00261 BOOL HandleRelease(const H245_TerminalCapabilitySetRelease & pdu);
00262 void HandleTimeout(PTimer &, INT);
00263
00264 BOOL HasSentCapabilities() const { return state == e_Sent; }
00265 BOOL HasReceivedCapabilities() const { return receivedCapabilites; }
00266
00267 protected:
00268 enum States {
00269 e_Idle, e_InProgress, e_Sent,
00270 e_NumStates
00271 } state;
00272 #if PTRACING
00273 static const char * const StateNames[e_NumStates];
00274 friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
00275 #endif
00276
00277 unsigned inSequenceNumber;
00278 unsigned outSequenceNumber;
00279
00280 BOOL receivedCapabilites;
00281 };
00282
00283
00286 class H245NegLogicalChannel : public H245Negotiator
00287 {
00288 PCLASSINFO(H245NegLogicalChannel, H245Negotiator);
00289
00290 public:
00291 H245NegLogicalChannel(H323EndPoint & endpoint,
00292 H323Connection & connection,
00293 const H323ChannelNumber & channelNumber);
00294 H245NegLogicalChannel(H323EndPoint & endpoint,
00295 H323Connection & connection,
00296 H323Channel & channel);
00297 ~H245NegLogicalChannel();
00298
00299 virtual BOOL Open(
00300 const H323Capability & capability,
00301 unsigned sessionID,
00302 unsigned replacementFor = 0
00303 );
00304 virtual BOOL Close();
00305 virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
00306 virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00307 virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00308 virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
00309 virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
00310 virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00311 virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
00312 virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00313 virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00314 virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00315 virtual void HandleTimeout(PTimer &, INT);
00316
00317 H323Channel * GetChannel();
00318
00319
00320 protected:
00321 virtual BOOL OpenWhileLocked(
00322 const H323Capability & capability,
00323 unsigned sessionID,
00324 unsigned replacementFor = 0
00325 );
00326 virtual BOOL CloseWhileLocked();
00327 virtual void Release();
00328
00329
00330 H323Channel * channel;
00331
00332 H323ChannelNumber channelNumber;
00333
00334 enum States {
00335 e_Released,
00336 e_AwaitingEstablishment,
00337 e_Established,
00338 e_AwaitingRelease,
00339 e_AwaitingConfirmation,
00340 e_AwaitingResponse,
00341 e_NumStates
00342 } state;
00343 #if PTRACING
00344 static const char * const StateNames[e_NumStates];
00345 friend ostream & operator<<(ostream & o, States s) { return o << StateNames[s]; }
00346 #endif
00347
00348
00349 friend class H245NegLogicalChannels;
00350 };
00351
00352
00353 PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
00354
00357 class H245NegLogicalChannels : public H245Negotiator
00358 {
00359 PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
00360
00361 public:
00362 H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
00363
00364 virtual void Add(H323Channel & channel);
00365
00366 virtual BOOL Open(
00367 const H323Capability & capability,
00368 unsigned sessionID,
00369 unsigned replacementFor = 0
00370 );
00371 virtual BOOL Close(unsigned channelNumber, BOOL fromRemote);
00372 virtual BOOL HandleOpen(const H245_OpenLogicalChannel & pdu);
00373 virtual BOOL HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00374 virtual BOOL HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00375 virtual BOOL HandleReject(const H245_OpenLogicalChannelReject & pdu);
00376 virtual BOOL HandleClose(const H245_CloseLogicalChannel & pdu);
00377 virtual BOOL HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00378 virtual BOOL HandleRequestClose(const H245_RequestChannelClose & pdu);
00379 virtual BOOL HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00380 virtual BOOL HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00381 virtual BOOL HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00382
00383 H323ChannelNumber GetNextChannelNumber();
00384 PINDEX GetSize() const { return channels.GetSize(); }
00385 H323Channel * GetChannelAt(PINDEX i);
00386 H323Channel * FindChannel(unsigned channelNumber, BOOL fromRemote);
00387 H245NegLogicalChannel & GetNegLogicalChannelAt(PINDEX i);
00388 H245NegLogicalChannel * FindNegLogicalChannel(unsigned channelNumber, BOOL fromRemote);
00389 H323Channel * FindChannelBySession(unsigned rtpSessionId, BOOL fromRemote);
00390 void RemoveAll();
00391
00392 protected:
00393 H323ChannelNumber lastChannelNumber;
00394 H245LogicalChannelDict channels;
00395 };
00396
00397
00400 class H245NegRequestMode : public H245Negotiator
00401 {
00402 PCLASSINFO(H245NegRequestMode, H245Negotiator);
00403
00404 public:
00405 H245NegRequestMode(H323EndPoint & endpoint, H323Connection & connection);
00406
00407 virtual BOOL StartRequest(const PString & newModes);
00408 virtual BOOL StartRequest(const H245_ArrayOf_ModeDescription & newModes);
00409 virtual BOOL HandleRequest(const H245_RequestMode & pdu);
00410 virtual BOOL HandleAck(const H245_RequestModeAck & pdu);
00411 virtual BOOL HandleReject(const H245_RequestModeReject & pdu);
00412 virtual BOOL HandleRelease(const H245_RequestModeRelease & pdu);
00413 virtual void HandleTimeout(PTimer &, INT);
00414
00415 protected:
00416 BOOL awaitingResponse;
00417 unsigned inSequenceNumber;
00418 unsigned outSequenceNumber;
00419 };
00420
00421
00424 class H245NegRoundTripDelay : public H245Negotiator
00425 {
00426 PCLASSINFO(H245NegRoundTripDelay, H245Negotiator);
00427
00428 public:
00429 H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
00430
00431 BOOL StartRequest();
00432 BOOL HandleRequest(const H245_RoundTripDelayRequest & pdu);
00433 BOOL HandleResponse(const H245_RoundTripDelayResponse & pdu);
00434 void HandleTimeout(PTimer &, INT);
00435
00436 PTimeInterval GetRoundTripDelay() const { return roundTripTime; }
00437 BOOL IsRemoteOffline() const { return retryCount == 0; }
00438
00439 protected:
00440 BOOL awaitingResponse;
00441 unsigned sequenceNumber;
00442 PTimeInterval tripStartTime;
00443 PTimeInterval roundTripTime;
00444 unsigned retryCount;
00445 };
00446
00447
00448 #endif // __OPAL_H323NEG_H
00449
00450