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