kr_plat_ao_epoc.cpp

Go to the documentation of this file.
00001 #include "kr_plat_ao.h"
00002 
00003 #include "ac_app_context.h"
00004 #include "bb_blackboard.h"
00005 #include "er_errors.h"
00006 #include "kr_diskspace.h"
00007 #include "kr_sms_trigger_epoc.hpp"
00008 #include "sa_sensor_list_log_db.h"
00009 #include "ut_diskspace_epoc.hpp"
00010 #include "ut_telephony_epoc.h"
00011 #include "ut_retry_epoc.hpp"
00012 #include "utils_cl2.h"
00013 
00014 // --------------------------------------------------
00015 // disk space observing
00016 // --------------------------------------------------
00017 
00018 /***koog 
00019 (require codegen/symbian-cxx)
00020 (ctor-defines/spec
00021  "CDiskObserver" ;; name
00022  "" ;; args
00023  "" ;; inits
00024  "" ;; ctor
00025  #t ;; ConstructL
00026 )
00027  ***/
00028 #define CTOR_DECL_CDiskObserver  \
00029 public: static CDiskObserver* NewLC(); \
00030 public: static CDiskObserver* NewL(); \
00031 private: CDiskObserver(); \
00032 private: void ConstructL();
00033 
00034 #define CTOR_IMPL_CDiskObserver  \
00035 CDiskObserver* CDiskObserver::NewLC() \
00036 { \
00037   CDiskObserver* obj = new (ELeave) CDiskObserver(); \
00038   CleanupStack::PushL(obj); \
00039   obj->ConstructL(); \
00040   return obj; \
00041 } \
00042  \
00043 CDiskObserver* CDiskObserver::NewL() \
00044 { \
00045   CDiskObserver* obj = CDiskObserver::NewLC(); \
00046   CleanupStack::Pop(obj); \
00047   return obj; \
00048 } \
00049  \
00050 CDiskObserver::CDiskObserver() \
00051 {}
00052 /***end***/
00053 NONSHARABLE_CLASS(CDiskObserver) : public CBase, public MDiskSpace
00054 {
00055   CTOR_DECL_CDiskObserver;
00056 
00057  public:
00058   ~CDiskObserver();
00059 
00060  private:
00061   virtual void DiskSpaceNotify(TInt aDrive, TInt errCode);
00062 
00063  private:
00064   DEF_SESSION(RFs, iFs);
00065   CDiskSpaceNotifier* iNotifier;
00066 };
00067 
00068 CTOR_IMPL_CDiskObserver;
00069 
00070 void CDiskObserver::ConstructL()
00071 {
00072   TChar driveLetter = DATABASE_DRIVE_LETTER;
00073   TInt driveNum = 0;
00074   User::LeaveIfError(RFs::CharToDrive(driveLetter, driveNum));
00075 
00076   LEAVE_IF_ERROR_OR_SET_SESSION_OPEN(iFs, iFs.Connect());
00077   int database_disk_threshold = ac_STATIC_GET(database_disk_threshold);
00078   iNotifier = CDiskSpaceNotifier::NewL(iFs, driveNum,
00079                this, 
00080                (TInt64)database_disk_threshold);
00081 }
00082 
00083 CDiskObserver::~CDiskObserver()
00084 {
00085   delete iNotifier;
00086   SESSION_CLOSE_IF_OPEN(iFs);
00087 }
00088 
00089 void CDiskObserver::DiskSpaceNotify(TInt aDrive, TInt errCode)
00090 {
00091   (void)aDrive;
00092   if (errCode) {
00093     // We are not really expecting any errors here, not any that are
00094     // in the API docs, anyway.
00095     logg("unexpected error in disk observer: %d", errCode);
00096   } else {
00097     // There are a number of causes why we might get an
00098     // RFs::NotifyDiskSpace() event, so we have to do some further
00099     // checking here.
00100     TRAPD(errCode, CheckLoggingMediumReadyL(iFs));
00101     if (errCode) {
00102       // One issue here is that we do not really know if it is safe to
00103       // try to log this error to the database. Possibly not, so the
00104       // debug log, if any, shall have to do.
00105       ex_txtlog_error(errCode);
00106       if (errCode == KErrDiskFull) {
00107   er_fatal_disk_low;
00108       } else {
00109         // A typical cause for getting here is attaching an USB cable,
00110         // resulting in KErrNotReady (-18). Hence this visible message
00111         // is somewhat appropriate.
00112   er_fatal_disk_not_ready;
00113       }
00114     }
00115   }
00116 }
00117 
00118 // --------------------------------------------------
00119 // network registration status observing
00120 // --------------------------------------------------
00121 
00122 /***koog 
00123 (require codegen/symbian-cxx)
00124 (ctor-defines/spec
00125  "CRegistrationObserver" ;; name
00126  "" ;; args
00127  "" ;; inits
00128  "" ;; ctor
00129  #t ;; ConstructL
00130 )
00131  ***/
00132 #define CTOR_DECL_CRegistrationObserver  \
00133 public: static CRegistrationObserver* NewLC(); \
00134 public: static CRegistrationObserver* NewL(); \
00135 private: CRegistrationObserver(); \
00136 private: void ConstructL();
00137 
00138 #define CTOR_IMPL_CRegistrationObserver  \
00139 CRegistrationObserver* CRegistrationObserver::NewLC() \
00140 { \
00141   CRegistrationObserver* obj = new (ELeave) CRegistrationObserver(); \
00142   CleanupStack::PushL(obj); \
00143   obj->ConstructL(); \
00144   return obj; \
00145 } \
00146  \
00147 CRegistrationObserver* CRegistrationObserver::NewL() \
00148 { \
00149   CRegistrationObserver* obj = CRegistrationObserver::NewLC(); \
00150   CleanupStack::Pop(obj); \
00151   return obj; \
00152 } \
00153  \
00154 CRegistrationObserver::CRegistrationObserver() \
00155 {}
00156 /***end***/
00157 
00158 #define This CRegistrationObserver
00159 
00160 NONSHARABLE_CLASS(This) : 
00161   public CBase, 
00162   public MObserverObs_NetworkRegistration
00163 {
00164   CTOR_DECL_CRegistrationObserver;
00165 
00166  public:
00167   ~CRegistrationObserver();
00168 
00169  private:
00170   virtual void ObservedData_NetworkRegistration(TData_NetworkRegistration const &aData);
00171   virtual void Failed_NetworkRegistration(TInt aError);
00172   virtual void InFlightMode_NetworkRegistration();
00173 
00174  private:
00175   CObserverAo_NetworkRegistration* iObserver;
00176 };
00177 
00178 CTOR_IMPL_CRegistrationObserver;
00179 
00180 void This::ConstructL()
00181 {
00182   ac_AppContext* ac = ac_get_global_AppContext();
00183 
00184   iObserver = CObserverAo_NetworkRegistration::NewL(ac, *this);
00185 }
00186 
00187 This::~CRegistrationObserver()
00188 {
00189   delete iObserver;
00190 }
00191 
00192 void This::ObservedData_NetworkRegistration(TData_NetworkRegistration const &aData)
00193 {
00194   int status = aData.iRegStatus;
00195   logg("network registration status: %d", status);
00196   LogDb* logDb = ac_global_LogDb;
00197   if (logDb) {
00198     log_db_log_registration(logDb, status, NULL);
00199   }
00200 }
00201 
00202 void This::Failed_NetworkRegistration(TInt aError)
00203 {
00204   er_log_symbian(0, aError, 
00205      "network registration status query failure (giving up)");
00206 }
00207 
00208 void This::InFlightMode_NetworkRegistration()
00209 {
00210   logt("network registration observer sleeping (flight mode)");
00211 }
00212 
00213 #undef This
00214 
00215 // --------------------------------------------------
00216 // network information observing
00217 // --------------------------------------------------
00218 
00219 // In flight mode, we have been seeing KErrAccessDenied (-21). The
00220 // current implementation avoids querying in flight mode.
00221 
00222 /***koog 
00223 (require codegen/symbian-cxx)
00224 (ctor-defines/spec
00225  "CNetworkObserver" ;; name
00226  "" ;; args
00227  "" ;; inits
00228  "" ;; ctor
00229  #t ;; ConstructL
00230 )
00231  ***/
00232 #define CTOR_DECL_CNetworkObserver  \
00233 public: static CNetworkObserver* NewLC(); \
00234 public: static CNetworkObserver* NewL(); \
00235 private: CNetworkObserver(); \
00236 private: void ConstructL();
00237 
00238 #define CTOR_IMPL_CNetworkObserver  \
00239 CNetworkObserver* CNetworkObserver::NewLC() \
00240 { \
00241   CNetworkObserver* obj = new (ELeave) CNetworkObserver(); \
00242   CleanupStack::PushL(obj); \
00243   obj->ConstructL(); \
00244   return obj; \
00245 } \
00246  \
00247 CNetworkObserver* CNetworkObserver::NewL() \
00248 { \
00249   CNetworkObserver* obj = CNetworkObserver::NewLC(); \
00250   CleanupStack::Pop(obj); \
00251   return obj; \
00252 } \
00253  \
00254 CNetworkObserver::CNetworkObserver() \
00255 {}
00256 /***end***/
00257 
00258 #define This CNetworkObserver
00259 
00260 NONSHARABLE_CLASS(This) : 
00261   public CBase, 
00262   public MObserverObs_NetworkInfo
00263 {
00264   CTOR_DECL_CNetworkObserver;
00265 
00266  public:
00267   ~CNetworkObserver();
00268 
00269  private:
00270   virtual void ObservedData_NetworkInfo(TData_NetworkInfo const &aData);
00271   virtual void ReportTransientError_NetworkInfo(TInt aError);
00272   virtual void RetriesExhausted_NetworkInfo();
00273   virtual void InFlightMode_NetworkInfo();
00274 
00275  private:
00276   CObserverAo_NetworkInfo* iObserver;
00277   TData_NetworkInfo iOldData;
00278   TData_NetworkInfo iFlightModeData;
00279 };
00280 
00281 CTOR_IMPL_CNetworkObserver;
00282 
00283 void This::ConstructL()
00284 {
00285   // The default constructor basically gives us what we want, but we
00286   // add the "operator" name to help us see from the logs what is
00287   // going on.
00288   _LIT(KFlightModeText, "(flight mode)");
00289   iFlightModeData.iLongName.Copy(KFlightModeText);
00290 
00291   ac_AppContext* ac = ac_get_global_AppContext();
00292   iObserver = CObserverAo_NetworkInfo::NewL(ac, *this);
00293 }
00294 
00295 This::~CNetworkObserver()
00296 {
00297   delete iObserver;
00298 }
00299 
00300 void This::ObservedData_NetworkInfo(TData_NetworkInfo const &aData)
00301 {
00302   // Log operator long name, if it has changed.
00303   {
00304     if (aData.iLongName != iOldData.iLongName) {
00305       LogDb* logDb = ac_global_LogDb;
00306       HBufC8* text8 = ConvToUtf8ZL(aData.iLongName);
00307       CleanupStack::PushL(text8);
00308       guilogf("operator: name '%s'", (char*)text8->Ptr());
00309       log_db_log_operator(logDb, (const char*)text8->Ptr(), NULL);
00310       kr_Controller_set_operator_name(ac_global_Controller, 
00311               (const char*)text8->Ptr());
00312       CleanupStack::PopAndDestroy(text8);
00313     }
00314   }
00315 
00316   // Propagate any changed mobile network country code.
00317   if (iOldData.iCountryCode != aData.iCountryCode) {
00318     TLex lex(aData.iCountryCode);
00319     int mcc;
00320     TInt errCode = lex.Val(mcc);
00321     if (errCode) 
00322       // Unexpected MCC.
00323       mcc = -1;
00324     // Notify interested parties.
00325     kr_Controller_set_current_mcc(ac_global_Controller, mcc);
00326   }
00327 
00328   // Post data for those interested in GSM cell ID changes.
00329   if ((iOldData.iCountryCode != aData.iCountryCode) ||
00330       (iOldData.iNetworkId != aData.iNetworkId) ||
00331       (iOldData.iLocationAreaCode != aData.iLocationAreaCode) ||
00332       (iOldData.iCellId != aData.iCellId)) {
00333     bb_Blackboard_notify(ac_global_Blackboard,
00334        bb_dt_cell_id,
00335        (gpointer)&aData, 0);
00336   }
00337 
00338   iOldData = aData;
00339 
00340   bb_Blackboard_notify(ac_global_Blackboard,
00341            bb_dt_network_info,
00342            (gpointer)&aData, 0);
00343 }
00344 
00345 void This::ReportTransientError_NetworkInfo(TInt aError)
00346 {
00347   er_log_symbian(0, aError, "network info query failure (transient)");
00348 }
00349 
00350 void This::RetriesExhausted_NetworkInfo()
00351 {
00352   er_log_none(er_FATAL, "network info queries failing");
00353 }
00354 
00355 void This::InFlightMode_NetworkInfo()
00356 {
00357   logt("network info observer sleeping (flight mode)");
00358   ObservedData_NetworkInfo(iFlightModeData);
00359 }
00360 
00361 #undef This
00362 
00363 // --------------------------------------------------
00364 // network signal strength observing
00365 // --------------------------------------------------
00366 
00367 /* We require retries here in particular, as we have seen KErrOverflow frequently. In fact we have had enough many failures so as to run out of retries.
00368 
00369    xxx Should find out why this is, if there are conditions under which it is not okay to make this query. Cannot find any information about the cause, but something to account for is that "this functionality is not available when the phone is in flight mode".
00370 
00371    We try to account for the above by observing flightmode status, and refraining from making requests (or having outstanding requests) when flightmode is on. We shall see if this addresses the issue.
00372 
00373    xxx Could more easily implement based on CObserverAo_SignalStrength.
00374 */
00375 
00376 /***koog 
00377 (require codegen/symbian-cxx)
00378 (ctor-defines/spec
00379  "CSignalObserver" ;; name
00380  "" ;; args
00381  "" ;; inits
00382  "" ;; ctor
00383  #t ;; ConstructL
00384 )
00385  ***/
00386 #define CTOR_DECL_CSignalObserver  \
00387 public: static CSignalObserver* NewLC(); \
00388 public: static CSignalObserver* NewL(); \
00389 private: CSignalObserver(); \
00390 private: void ConstructL();
00391 
00392 #define CTOR_IMPL_CSignalObserver  \
00393 CSignalObserver* CSignalObserver::NewLC() \
00394 { \
00395   CSignalObserver* obj = new (ELeave) CSignalObserver(); \
00396   CleanupStack::PushL(obj); \
00397   obj->ConstructL(); \
00398   return obj; \
00399 } \
00400  \
00401 CSignalObserver* CSignalObserver::NewL() \
00402 { \
00403   CSignalObserver* obj = CSignalObserver::NewLC(); \
00404   CleanupStack::Pop(obj); \
00405   return obj; \
00406 } \
00407  \
00408 CSignalObserver::CSignalObserver() \
00409 {}
00410 /***end***/
00411 
00412 #define This CSignalObserver
00413 
00414 NONSHARABLE_CLASS(This) : 
00415   public CBase, 
00416   public MGetterObs_SignalStrength,
00417   public MNotifyObs_SignalStrength,
00418   public MRetryAoObserver
00419 {
00420   CTOR_DECL_CSignalObserver;
00421 
00422  public:
00423   ~CSignalObserver();
00424 
00425  private:
00426   virtual void RetryTimerExpired(CRetryAo* src, TInt errCode);
00427   virtual void GotData_SignalStrength(TInt aError);
00428   virtual void ChangedData_SignalStrength(TInt aError);
00429   void HandleSignal(TInt aError, TData_SignalStrength const & aData);
00430 
00431  private:
00432   CRetryAo* iRetryAo;
00433   TBool iGetterDone;
00434   CGetterAo_SignalStrength* iGetter;
00435   CNotifyAo_SignalStrength* iNotifier;
00436 
00437  private:
00438   void MakeRequest();
00439   void Cancel();
00440 
00441   // Flight mode observation.
00442  private:
00443   bb_Closure iClosure;
00444   void BbRegisterL();
00445   void BbUnregister();
00446   TBool GetFlightMode();
00447  public:
00448   void HandleFlightModeChange();
00449 };
00450 
00451 CTOR_IMPL_CSignalObserver;
00452 
00453 void This::MakeRequest()
00454 {
00455   if (iGetterDone)
00456     iNotifier->MakeRequest();
00457   else
00458     iGetter->MakeRequest();
00459 }
00460 
00461 void This::Cancel()
00462 {
00463   iRetryAo->Cancel();
00464   iNotifier->Cancel();
00465   iGetter->Cancel();
00466 
00467   iRetryAo->ResetFailures();
00468 
00469   // Once we begin observing again, we want a reading immediately,
00470   // rather than waiting for a change in readings.
00471   iGetterDone = EFalse;
00472 }
00473 
00474 static void SignalObserverFlightModeChanged
00475 (bb_Blackboard* bb, enum bb_DataType dt,
00476  gpointer data, int len, gpointer arg)
00477 {
00478   (void)dt;
00479   (void)len;
00480   This* self = (This*)arg;
00481   self->HandleFlightModeChange();
00482 }
00483 
00484 void This::HandleFlightModeChange()
00485 {
00486   TBool fm = GetFlightMode();
00487   if (fm) {
00488     Cancel();
00489 
00490     // Notify with value +1 to indicate no signal.
00491     kr_Controller_set_signal_strength(ac_global_Controller, 1);
00492   } else {
00493     MakeRequest();
00494   }
00495 }
00496 
00497 TBool This::GetFlightMode()
00498 {
00499   // Initial value (internal).
00500   bb_Blackboard* bb = ac_global_Blackboard;
00501   bb_Board* bd = bb_Blackboard_board(bb);
00502   return bd->flightmode;
00503 }
00504 
00505 void This::BbRegisterL()
00506 {
00507   // Closure init.
00508   iClosure.changed = SignalObserverFlightModeChanged;
00509   iClosure.arg = this;
00510 
00511   // Registration proper.
00512   bb_Blackboard* bb = ac_global_Blackboard;
00513   if (!bb_Blackboard_register(bb, bb_dt_flightmode, iClosure, NULL))
00514     User::LeaveNoMemory();
00515 }
00516 
00517 void This::BbUnregister()
00518 {
00519   bb_Blackboard_unregister(ac_global_Blackboard, iClosure);
00520 }
00521 
00522 void This::ConstructL()
00523 {
00524   BbRegisterL();
00525 
00526   ac_AppContext* ac = ac_get_global_AppContext();
00527 
00528   iRetryAo = CRetryAo::NewL(*this, 20, 60);
00529 
00530   iGetter = new (ELeave) CGetterAo_SignalStrength(ac_Telephony(ac), *this);
00531   iNotifier = new (ELeave) CNotifyAo_SignalStrength(ac_Telephony(ac), *this);
00532 
00533   TBool fm = GetFlightMode();
00534   if (!fm) {
00535     // We will not be getting any signal strength reading for as long
00536     // as flightmode is on. Makes sense.
00537     MakeRequest();
00538   }
00539 }
00540 
00541 This::~CSignalObserver()
00542 {
00543   BbUnregister();
00544   delete iGetter;
00545   delete iNotifier;
00546   delete iRetryAo;
00547 }
00548 
00549 void This::RetryTimerExpired(CRetryAo* src, TInt errCode)
00550 {
00551   (void)src;
00552   if (errCode) {
00553     LogDb* logDb = ac_global_LogDb;
00554     ex_dblog_fatal_error_msg(logDb, "retry timer error", errCode);
00555   } else {
00556     MakeRequest();
00557   }
00558 }
00559 
00560 void This::GotData_SignalStrength(TInt aError)
00561 {
00562   HandleSignal(aError, iGetter->Data());
00563   if (!aError) 
00564     iGetterDone = ETrue;
00565 }
00566 
00567 void This::ChangedData_SignalStrength(TInt aError)
00568 {
00569   HandleSignal(aError, iNotifier->Data());
00570 }
00571 
00572 void This::HandleSignal(TInt aError, 
00573       TData_SignalStrength const & aData)
00574 {
00575   LogDb* logDb = ac_global_LogDb;
00576   if (aError) {
00577     ex_dblog_error_msg(logDb, "signal strength query failure", aError, NULL);
00578     if (!iRetryAo->Retry()) {
00579       er_log_none(er_FATAL, "signal strength queries failing");
00580     }
00581   } else {
00582     iRetryAo->ResetFailures();
00583 
00584     int dbm = -(aData.iSignalStrength);
00585     int bars = aData.iBar;
00586     guilogf("signal: %d dBm (%d bars)", dbm, bars);
00587     log_db_log_signal(logDb, dbm, bars, NULL);
00588     iNotifier->MakeRequest();
00589 
00590     // Notify interested parties. Indiscriminately, receiver must
00591     // check for duplicates.
00592     kr_Controller_set_signal_strength(ac_global_Controller, dbm);
00593   }
00594 }
00595 
00596 #undef This
00597 
00598 // --------------------------------------------------
00599 // auxiliary controller
00600 // --------------------------------------------------
00601 
00602 struct _kr_PlatAo {
00603   CDiskObserver* iDiskObserver;
00604   CRegistrationObserver* iRegistrationObserver;
00605   CNetworkObserver* iNetworkObserver;
00606   CSignalObserver* iSignalObserver;
00607   CSmsTrigger* iSmsTrigger;
00608 };
00609 
00610 extern "C" kr_PlatAo* kr_PlatAo_new(GError** error)
00611 {
00612   ac_AppContext* ac = ac_get_global_AppContext();
00613 
00614   kr_PlatAo* self = g_try_new0(kr_PlatAo, 1);
00615   if (G_UNLIKELY(!self)) {
00616     if (error) *error = gx_error_no_memory;
00617     return NULL;
00618   }
00619 
00620   TRAPD(errCode, self->iDiskObserver = CDiskObserver::NewL());
00621   if (G_UNLIKELY(errCode)) {
00622     kr_PlatAo_destroy(self);
00623     if (error)
00624       *error = gx_error_new(domain_symbian, errCode, 
00625           "disk observer creation failure: %s (%d)", 
00626           plat_error_strerror(errCode), errCode);
00627     return NULL;
00628   }
00629 
00630   TRAP(errCode, self->iRegistrationObserver = CRegistrationObserver::NewL());
00631   if (G_UNLIKELY(errCode)) {
00632     kr_PlatAo_destroy(self);
00633     if (error)
00634       *error = gx_error_new(domain_symbian, errCode, 
00635           "registration observer creation failure: %s (%d)", 
00636           plat_error_strerror(errCode), errCode);
00637     return NULL;
00638   }
00639 
00640 #if __CAN_GET_NETWORK_INFO__
00641   TRAP(errCode, self->iNetworkObserver = CNetworkObserver::NewL());
00642   if (G_UNLIKELY(errCode)) {
00643     kr_PlatAo_destroy(self);
00644     if (error)
00645       *error = gx_error_new(domain_symbian, errCode, 
00646           "network observer creation failure: %s (%d)", 
00647           plat_error_strerror(errCode), errCode);
00648     return NULL;
00649   }
00650 #endif
00651 
00652   TRAP(errCode, self->iSignalObserver = CSignalObserver::NewL());
00653   if (G_UNLIKELY(errCode)) {
00654     kr_PlatAo_destroy(self);
00655     if (error)
00656       *error = gx_error_new(domain_symbian, errCode, 
00657           "signal strength observer creation failure: %s (%d)", 
00658           plat_error_strerror(errCode), errCode);
00659     return NULL;
00660   }
00661 
00662 #if __FEATURE_REMOKON__
00663   TRAP(errCode, self->iSmsTrigger = CSmsTrigger::NewL(ac));
00664   if (G_UNLIKELY(errCode)) {
00665     kr_PlatAo_destroy(self);
00666     if (error)
00667       *error = gx_error_new(domain_symbian, errCode, 
00668           "SMS trigger observer creation failure: %s (%d)", 
00669           plat_error_strerror(errCode), errCode);
00670     return NULL;
00671   }
00672 #endif
00673 
00674   return self;
00675 }
00676 
00677 extern "C" void kr_PlatAo_destroy(kr_PlatAo* self)
00678 {
00679   if (self) {
00680 #if __FEATURE_REMOKON__
00681     delete self->iSmsTrigger;
00682 #endif
00683     delete self->iSignalObserver;
00684     delete self->iNetworkObserver;
00685     delete self->iRegistrationObserver;
00686     delete self->iDiskObserver;
00687     g_free(self);
00688   }
00689 }
00690 
00691 /**
00692 
00693 kr_plat_ao_epoc.cpp
00694 
00695 Copyright 2009 Helsinki Institute for Information Technology (HIIT)
00696 and the authors. All rights reserved.
00697 
00698 Authors: Tero Hasu <tero.hasu@hut.fi>
00699 
00700 Permission is hereby granted, free of charge, to any person
00701 obtaining a copy of this software and associated documentation files
00702 (the "Software"), to deal in the Software without restriction,
00703 including without limitation the rights to use, copy, modify, merge,
00704 publish, distribute, sublicense, and/or sell copies of the Software,
00705 and to permit persons to whom the Software is furnished to do so,
00706 subject to the following conditions:
00707 
00708 The above copyright notice and this permission notice shall be
00709 included in all copies or substantial portions of the Software.
00710 
00711 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00712 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00713 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00714 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00715 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00716 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00717 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00718 SOFTWARE.
00719 
00720  **/

ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:54 2011 by Doxygen 1.6.1