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