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, HandleTimeoutUnlocked);
00066 virtual void HandleTimeout();
00067
00068 H323EndPoint & endpoint;
00069 H323Connection & connection;
00070 PTimer replyTimer;
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();
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 = false);
00130 void Stop(PBoolean dec = false);
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();
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();
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 void Release();
00199
00200
00201 H323Channel * channel;
00202
00203 H323ChannelNumber channelNumber;
00204
00205 enum States {
00206 e_Released,
00207 e_AwaitingEstablishment,
00208 e_Established,
00209 e_AwaitingRelease,
00210 e_AwaitingConfirmation,
00211 e_AwaitingResponse,
00212 e_NumStates
00213 } state;
00214 #if PTRACING
00215 static const char * GetStateName(States s);
00216 friend ostream & operator<<(ostream & o, States s) { return o << GetStateName(s); }
00217 #endif
00218
00219
00220 friend class H245NegLogicalChannels;
00221 };
00222
00223
00224 PDICTIONARY(H245LogicalChannelDict, H323ChannelNumber, H245NegLogicalChannel);
00225
00228 class H245NegLogicalChannels : public H245Negotiator
00229 {
00230 PCLASSINFO(H245NegLogicalChannels, H245Negotiator);
00231
00232 public:
00233 H245NegLogicalChannels(H323EndPoint & endpoint, H323Connection & connection);
00234
00235 virtual void Add(H323Channel & channel);
00236
00237 virtual PBoolean Open(
00238 const H323Capability & capability,
00239 unsigned sessionID,
00240 unsigned replacementFor = 0
00241 );
00242 virtual PBoolean Close(unsigned channelNumber, PBoolean fromRemote);
00243 virtual PBoolean HandleOpen(const H245_OpenLogicalChannel & pdu);
00244 virtual PBoolean HandleOpenAck(const H245_OpenLogicalChannelAck & pdu);
00245 virtual PBoolean HandleOpenConfirm(const H245_OpenLogicalChannelConfirm & pdu);
00246 virtual PBoolean HandleReject(const H245_OpenLogicalChannelReject & pdu);
00247 virtual PBoolean HandleClose(const H245_CloseLogicalChannel & pdu);
00248 virtual PBoolean HandleCloseAck(const H245_CloseLogicalChannelAck & pdu);
00249 virtual PBoolean HandleRequestClose(const H245_RequestChannelClose & pdu);
00250 virtual PBoolean HandleRequestCloseAck(const H245_RequestChannelCloseAck & pdu);
00251 virtual PBoolean HandleRequestCloseReject(const H245_RequestChannelCloseReject & pdu);
00252 virtual PBoolean HandleRequestCloseRelease(const H245_RequestChannelCloseRelease & pdu);
00253
00254 H323ChannelNumber GetNextChannelNumber();
00255 PINDEX GetSize() const { return channels.GetSize(); }
00256 H323Channel * GetChannelAt(PINDEX i);
00257 H323Channel * FindChannel(unsigned channelNumber, PBoolean fromRemote);
00258 H245NegLogicalChannel & GetNegLogicalChannelAt(PINDEX i);
00259 H245NegLogicalChannel * FindNegLogicalChannel(unsigned channelNumber, PBoolean fromRemote);
00260 H323Channel * FindChannelBySession(unsigned rtpSessionId, PBoolean fromRemote);
00261 void RemoveAll();
00262
00263 protected:
00264 H323ChannelNumber lastChannelNumber;
00265 H245LogicalChannelDict channels;
00266 };
00267
00268
00271 class H245NegRequestMode : public H245Negotiator
00272 {
00273 PCLASSINFO(H245NegRequestMode, H245Negotiator);
00274
00275 public:
00276 H245NegRequestMode(H323EndPoint & endpoint, H323Connection & connection);
00277
00278 virtual PBoolean StartRequest(const PString & newModes);
00279 virtual PBoolean StartRequest(const H245_ArrayOf_ModeDescription & newModes);
00280 virtual PBoolean HandleRequest(const H245_RequestMode & pdu);
00281 virtual PBoolean HandleAck(const H245_RequestModeAck & pdu);
00282 virtual PBoolean HandleReject(const H245_RequestModeReject & pdu);
00283 virtual PBoolean HandleRelease(const H245_RequestModeRelease & pdu);
00284 virtual void HandleTimeout();
00285
00286 protected:
00287 PBoolean awaitingResponse;
00288 unsigned inSequenceNumber;
00289 unsigned outSequenceNumber;
00290 };
00291
00292
00295 class H245NegRoundTripDelay : public H245Negotiator
00296 {
00297 PCLASSINFO(H245NegRoundTripDelay, H245Negotiator);
00298
00299 public:
00300 H245NegRoundTripDelay(H323EndPoint & endpoint, H323Connection & connection);
00301
00302 PBoolean StartRequest();
00303 PBoolean HandleRequest(const H245_RoundTripDelayRequest & pdu);
00304 PBoolean HandleResponse(const H245_RoundTripDelayResponse & pdu);
00305 void HandleTimeout();
00306
00307 PTimeInterval GetRoundTripDelay() const { return roundTripTime; }
00308 PBoolean IsRemoteOffline() const { return retryCount == 0; }
00309
00310 protected:
00311 PBoolean awaitingResponse;
00312 unsigned sequenceNumber;
00313 PTimeInterval tripStartTime;
00314 PTimeInterval roundTripTime;
00315 unsigned retryCount;
00316 };
00317
00318
00319 #endif // OPAL_H323
00320
00321 #endif // OPAL_H323_H323NEG_H
00322
00323