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 #ifndef __OPAL_H323NEG_H
00035 #define __OPAL_H323NEG_H
00036
00037 #ifdef P_USE_PRAGMA
00038 #pragma interface
00039 #endif
00040
00041 #include <opal/buildopts.h>
00042
00043 #include <h323/h323pdu.h>
00044 #include <h323/channels.h>
00045
00046
00047 class H323EndPoint;
00048 class H323Connection;
00049
00050
00052
00055 class H245Negotiator : public PObject
00056 {
00057 PCLASSINFO(H245Negotiator, PObject);
00058
00059 public:
00060 H245Negotiator(H323EndPoint & endpoint, H323Connection & connection);
00061
00062 protected:
00063 PDECLARE_NOTIFIER(PTimer, H245Negotiator, HandleTimeout);
00064
00065 H323EndPoint & endpoint;
00066 H323Connection & connection;
00067 PTimer replyTimer;
00068 PMutex mutex;
00069 };
00070
00071
00074 class H245NegMasterSlaveDetermination : public H245Negotiator
00075 {
00076 PCLASSINFO(H245NegMasterSlaveDetermination, H245Negotiator);
00077
00078 public:
00079 H245NegMasterSlaveDetermination(H323EndPoint & endpoint, H323Connection & connection);
00080
00081 PBoolean Start(PBoolean renegotiate);
00082 void Stop();
00083 PBoolean HandleIncoming(const H245_MasterSlaveDetermination & pdu);
00084 PBoolean HandleAck(const H245_MasterSlaveDeterminationAck & pdu);
00085 PBoolean HandleReject(const H245_MasterSlaveDeterminationReject & pdu);
00086 PBoolean HandleRelease(const H245_MasterSlaveDeterminationRelease & pdu);
00087 void HandleTimeout(PTimer &, INT);
00088
00089 PBoolean IsMaster() const { return status == e_DeterminedMaster; }
00090 PBoolean IsDetermined() const { return state == e_Idle && status != e_Indeterminate; }
00091
00092 protected:
00093 PBoolean Restart();
00094
00095 enum States {
00096 e_Idle, e_Outgoing, e_Incoming,
00097 e_NumStates
00098 } state;
00099 #if PTRACING
00100 static const char * GetStateName(States s);
00101 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00102 #endif
00103
00104 DWORD determinationNumber;
00105 unsigned retryCount;
00106
00107 enum MasterSlaveStatus {
00108 e_Indeterminate, e_DeterminedMaster, e_DeterminedSlave,
00109 e_NumStatuses
00110 } status;
00111 #if PTRACING
00112 static const char * GetStatusName(MasterSlaveStatus s);
00113 friend ostream & operator<<(ostream & o , MasterSlaveStatus s) { return o << GetStatusName(s); }
00114 #endif
00115 };
00116
00117
00120 class H245NegTerminalCapabilitySet : public H245Negotiator
00121 {
00122 PCLASSINFO(H245NegTerminalCapabilitySet, H245Negotiator);
00123
00124 public:
00125 H245NegTerminalCapabilitySet(H323EndPoint & endpoint, H323Connection & connection);
00126
00127 PBoolean Start(PBoolean renegotiate, PBoolean empty = PFalse);
00128 void Stop(PBoolean dec = PFalse);
00129 PBoolean HandleIncoming(const H245_TerminalCapabilitySet & pdu);
00130 PBoolean HandleAck(const H245_TerminalCapabilitySetAck & pdu);
00131 PBoolean HandleReject(const H245_TerminalCapabilitySetReject & pdu);
00132 PBoolean HandleRelease(const H245_TerminalCapabilitySetRelease & pdu);
00133 void HandleTimeout(PTimer &, INT);
00134
00135 bool HasSentCapabilities() const { return state >= e_InProgress; }
00136 bool IsSendingCapabilities() const { return state == e_InProgress; }
00137 bool ConfrimedCapabilitiesSent() const { return state == e_Confirmed; }
00138 bool HasReceivedCapabilities() const { return receivedCapabilites; }
00139
00140 protected:
00141 enum States {
00142 e_Idle, e_InProgress, e_Confirmed,
00143 e_NumStates
00144 } state;
00145 #if PTRACING
00146 static const char * GetStateName(States s);
00147 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00148 #endif
00149
00150 unsigned inSequenceNumber;
00151 unsigned outSequenceNumber;
00152
00153 PBoolean receivedCapabilites;
00154 };
00155
00156
00159 class H245NegLogicalChannel : public H245Negotiator
00160 {
00161 PCLASSINFO(H245NegLogicalChannel, H245Negotiator);
00162
00163 public:
00164 H245NegLogicalChannel(H323EndPoint & endpoint,
00165 H323Connection & connection,
00166 const H323ChannelNumber & channelNumber);
00167 H245NegLogicalChannel(H323EndPoint & endpoint,
00168 H323Connection & connection,
00169 H323Channel & channel);
00170 ~H245NegLogicalChannel();
00171
00172 virtual PBoolean Open(
00173 const H323Capability & capability,
00174 unsigned sessionID,
00175 unsigned replacementFor = 0
00176 );
00177 virtual PBoolean Close();
00178 virtual PBoolean HandleOpen(const H245_OpenLogicalChannel & pdu);
00179 virtual PBoolean HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00180 virtual PBoolean HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00181 virtual PBoolean HandleReject(const H245_OpenLogicalChannelReject & pdu);
00182 virtual PBoolean HandleClose(const H245_CloseLogicalChannel & pdu);
00183 virtual PBoolean HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00184 virtual PBoolean HandleRequestClose(const H245_RequestChannelClose & pdu);
00185 virtual PBoolean HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00186 virtual PBoolean HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00187 virtual PBoolean HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00188 virtual void HandleTimeout(PTimer &, INT);
00189
00190 H323Channel * GetChannel();
00191
00192 bool IsAwaitingEstablishment() const { return state == e_AwaitingEstablishment; }
00193 bool IsEstablished() const { return state == e_Established; }
00194
00195 protected:
00196 virtual PBoolean OpenWhileLocked(
00197 const H323Capability & capability,
00198 unsigned sessionID,
00199 unsigned replacementFor = 0
00200 );
00201 virtual PBoolean CloseWhileLocked();
00202 virtual void Release();
00203
00204
00205 H323Channel * channel;
00206
00207 H323ChannelNumber channelNumber;
00208
00209 enum States {
00210 e_Released,
00211 e_AwaitingEstablishment,
00212 e_Established,
00213 e_AwaitingRelease,
00214 e_AwaitingConfirmation,
00215 e_AwaitingResponse,
00216 e_NumStates
00217 } state;
00218 #if PTRACING
00219 static const char * GetStateName(States s);
00220 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00221 #endif
00222
00223
00224 friend class H245NegLogicalChannels;
00225 };
00226
00227
00228 PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
00229
00232 class H245NegLogicalChannels : public H245Negotiator
00233 {
00234 PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
00235
00236 public:
00237 H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
00238
00239 virtual void Add(H323Channel & channel);
00240
00241 virtual PBoolean Open(
00242 const H323Capability & capability,
00243 unsigned sessionID,
00244 unsigned replacementFor = 0
00245 );
00246 virtual PBoolean Close(unsigned channelNumber, PBoolean fromRemote);
00247 virtual PBoolean HandleOpen(const H245_OpenLogicalChannel & pdu);
00248 virtual PBoolean HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00249 virtual PBoolean HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00250 virtual PBoolean HandleReject(const H245_OpenLogicalChannelReject & pdu);
00251 virtual PBoolean HandleClose(const H245_CloseLogicalChannel & pdu);
00252 virtual PBoolean HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00253 virtual PBoolean HandleRequestClose(const H245_RequestChannelClose & pdu);
00254 virtual PBoolean HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00255 virtual PBoolean HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00256 virtual PBoolean HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00257
00258 H323ChannelNumber GetNextChannelNumber();
00259 PINDEX GetSize() const { return channels.GetSize(); }
00260 H323Channel * GetChannelAt(PINDEX i);
00261 H323Channel * FindChannel(unsigned channelNumber, PBoolean fromRemote);
00262 H245NegLogicalChannel & GetNegLogicalChannelAt(PINDEX i);
00263 H245NegLogicalChannel * FindNegLogicalChannel(unsigned channelNumber, PBoolean fromRemote);
00264 H323Channel * FindChannelBySession(unsigned rtpSessionId, PBoolean fromRemote);
00265 void RemoveAll();
00266
00267 protected:
00268 H323ChannelNumber lastChannelNumber;
00269 H245LogicalChannelDict channels;
00270 };
00271
00272
00275 class H245NegRequestMode : public H245Negotiator
00276 {
00277 PCLASSINFO(H245NegRequestMode, H245Negotiator);
00278
00279 public:
00280 H245NegRequestMode(H323EndPoint & endpoint, H323Connection & connection);
00281
00282 virtual PBoolean StartRequest(const PString & newModes);
00283 virtual PBoolean StartRequest(const H245_ArrayOf_ModeDescription & newModes);
00284 virtual PBoolean HandleRequest(const H245_RequestMode & pdu);
00285 virtual PBoolean HandleAck(const H245_RequestModeAck & pdu);
00286 virtual PBoolean HandleReject(const H245_RequestModeReject & pdu);
00287 virtual PBoolean HandleRelease(const H245_RequestModeRelease & pdu);
00288 virtual void HandleTimeout(PTimer &, INT);
00289
00290 protected:
00291 PBoolean awaitingResponse;
00292 unsigned inSequenceNumber;
00293 unsigned outSequenceNumber;
00294 };
00295
00296
00299 class H245NegRoundTripDelay : public H245Negotiator
00300 {
00301 PCLASSINFO(H245NegRoundTripDelay, H245Negotiator);
00302
00303 public:
00304 H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
00305
00306 PBoolean StartRequest();
00307 PBoolean HandleRequest(const H245_RoundTripDelayRequest & pdu);
00308 PBoolean HandleResponse(const H245_RoundTripDelayResponse & pdu);
00309 void HandleTimeout(PTimer &, INT);
00310
00311 PTimeInterval GetRoundTripDelay() const { return roundTripTime; }
00312 PBoolean IsRemoteOffline() const { return retryCount == 0; }
00313
00314 protected:
00315 PBoolean awaitingResponse;
00316 unsigned sequenceNumber;
00317 PTimeInterval tripStartTime;
00318 PTimeInterval roundTripTime;
00319 unsigned retryCount;
00320 };
00321
00322
00323 #endif // __OPAL_H323NEG_H
00324
00325