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