00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #ifndef EVENTING_H_
00012 #define EVENTING_H_
00013
00014 #include <sys/time.h>
00015
00016 #include <qdom.h>
00017 #include <qurl.h>
00018 #include <quuid.h>
00019 #include <qdatetime.h>
00020 #include <qptrlist.h>
00021 #include <qdict.h>
00022
00023 #include "upnpimpl.h"
00024 #include "upnputil.h"
00025 #include "httpserver.h"
00026
00028
00030
00031 class SubscriberInfo
00032 {
00033 public:
00034
00035 TaskTime ttExpires;
00036 TaskTime ttLastNotified;
00037
00038 QString sUUID;
00039 QUrl qURL;
00040 unsigned short nKey;
00041 unsigned long nDuration;
00042
00043 public:
00044
00045
00046
00047 SubscriberInfo()
00048 {
00049 nKey = 0;
00050 nDuration = 0;
00051 ttLastNotified.tv_sec = 0;
00052 sUUID = QUuid::createUuid().toString();
00053 sUUID = sUUID.mid( 1, sUUID.length() - 2);
00054
00055
00056 }
00057
00058
00059
00060 SubscriberInfo( const QString &url, unsigned long duration )
00061 {
00062 nKey = 0;
00063 sUUID = QUuid::createUuid().toString();
00064 sUUID = sUUID.mid( 1, sUUID.length() - 2);
00065 qURL = url;
00066 nDuration = duration;
00067 ttLastNotified.tv_sec = 0;
00068
00069 SetExpireTime( nDuration );
00070 }
00071
00072
00073
00074 unsigned long IncrementKey()
00075 {
00076
00077
00078 if ((++nKey) == 0)
00079 nKey = 1;
00080
00081 return nKey;
00082 }
00083
00084 protected:
00085
00086 void SetExpireTime( unsigned long nSecs )
00087 {
00088 TaskTime tt;
00089 gettimeofday( &tt, NULL );
00090
00091 AddMicroSecToTaskTime( tt, (nSecs * 1000000) );
00092
00093 ttExpires = tt;
00094 }
00095
00096
00097 };
00098
00100
00101 class Subscribers : public QDict< SubscriberInfo >
00102 {
00103 public:
00104
00105 Subscribers()
00106 {
00107 setAutoDelete( true );
00108 }
00109 };
00110
00111 typedef QDictIterator< SubscriberInfo > SubscriberIterator;
00112
00114
00116
00117 class StateVariableBase
00118 {
00119 public:
00120
00121 bool m_bNotify;
00122 QString m_sName;
00123 TaskTime m_ttLastChanged;
00124
00125 public:
00126
00127 StateVariableBase( const QString &sName, bool bNotify = FALSE )
00128 {
00129 m_bNotify = bNotify;
00130 m_sName = sName;
00131 gettimeofday( &m_ttLastChanged, NULL );
00132 }
00133
00134 virtual QString ToString() = 0;
00135 };
00136
00138
00139 template< class T >
00140 class StateVariable : public StateVariableBase
00141 {
00142 private:
00143
00144 T m_value;
00145
00146 public:
00147
00148
00149
00150 StateVariable( const QString &sName, bool bNotify = FALSE ) : StateVariableBase( sName, bNotify )
00151 {
00152 }
00153
00154
00155
00156 StateVariable( const QString &sName, T value, bool bNotify = FALSE ) : StateVariableBase( sName, bNotify )
00157 {
00158 m_value = value;
00159 }
00160
00161
00162
00163 virtual QString ToString()
00164 {
00165 return QString( "%1" ).arg( m_value );
00166 }
00167
00168
00169
00170 T GetValue()
00171 {
00172 return m_value;
00173 }
00174
00175
00176
00177 void SetValue( T value )
00178 {
00179 if ( m_value != value )
00180 {
00181 m_value = value;
00182 gettimeofday( &m_ttLastChanged, NULL );
00183 }
00184 }
00185 };
00186
00188
00189 class StateVariables : public QDict< StateVariableBase >
00190 {
00191 protected:
00192
00193 virtual void Notify() = 0;
00194
00195 public:
00196
00197
00198
00199 StateVariables()
00200 {
00201 setAutoDelete( true );
00202 }
00203
00204
00205
00206 void AddVariable( StateVariableBase *pBase )
00207 {
00208 if (pBase != NULL)
00209 insert( pBase->m_sName, pBase );
00210 }
00211
00212
00213 template < class T >
00214 bool SetValue( const QString &sName, T value )
00215 {
00216 StateVariable< T > *pVariable = dynamic_cast< StateVariable< T > *>( find( sName ) );
00217
00218 if (pVariable == NULL)
00219 return false;
00220
00221 if ( pVariable->GetValue() != value)
00222 {
00223 pVariable->SetValue( value );
00224
00225 if (pVariable->m_bNotify)
00226 Notify();
00227 }
00228
00229 return true;
00230 }
00231
00232
00233
00234 template < class T >
00235 T GetValue( const QString &sName )
00236 {
00237 StateVariable< T > *pVariable = dynamic_cast< StateVariable< T > *>( find( sName ) );
00238
00239 if (pVariable != NULL)
00240 return pVariable->GetValue();
00241
00242 return T(0);
00243 }
00244
00245 };
00246
00247 typedef QDictIterator< StateVariableBase > StateVariableIterator;
00248
00249
00252
00253
00254
00257
00258 class Eventing : public HttpServerExtension,
00259 public StateVariables,
00260 public IPostProcess,
00261 public UPnpServiceImpl
00262 {
00263
00264 protected:
00265
00266 QMutex m_mutex;
00267
00268 QString m_sEventMethodName;
00269 Subscribers m_Subscribers;
00270
00271 int m_nSubscriptionDuration;
00272
00273 short m_nHoldCount;
00274
00275 SubscriberInfo *m_pInitializeSubscriber;
00276
00277 protected:
00278
00279 virtual void Notify ( );
00280 void NotifySubscriber ( SubscriberInfo *pInfo );
00281 int BuildNotifyBody ( QTextStream &ts, TaskTime ttLastNotified );
00282
00283 void HandleSubscribe ( HTTPRequest *pRequest );
00284 void HandleUnsubscribe( HTTPRequest *pRequest );
00285
00286
00287
00288 virtual QString GetServiceEventURL () { return m_sEventMethodName; }
00289
00290 public:
00291 Eventing ( const QString &sExtensionName, const QString &sEventMethodName );
00292 virtual ~Eventing ( );
00293
00294 virtual bool ProcessRequest( HttpWorkerThread *pThread, HTTPRequest *pRequest );
00295
00296 short HoldEvents ( );
00297 short ReleaseEvents ( );
00298
00299 void ExecutePostProcess( );
00300
00301
00302 };
00303
00304 #endif