epoc-indicator.cpp

Go to the documentation of this file.
00001 #include "epoc-indicator.hpp"
00002 
00003 #if __INDICATOR_ENABLED__
00004 
00005 #include "er_errors.h"
00006 #include "ld_logging.h"
00007 #include "sa_sensor_list_log_db.h"
00008 #include "utils_cl2.h"
00009 
00010 #include "common/assertions.h"
00011 #include "common/epoc-time.h"
00012 #include "common/error_list.h"
00013 #include "common/logging.h"
00014 #include "common/platform_error.h"
00015 #include "common/utilities.h"
00016 
00017 #include <stdlib.h> // rand
00018 
00019 // -------------------------------------------------------------------
00020 // the sensor object implementation...
00021 
00022 CTOR_IMPL_CSensor_indicator;
00023 
00024 void CSensor_indicator::ConstructL()
00025 {
00026   LEAVE_IF_ERROR_OR_SET_SESSION_OPEN(iTimer, iTimer.CreateLocal()); 
00027 }
00028 
00029 CSensor_indicator::~CSensor_indicator()
00030 {
00031   Cancel();
00032   SESSION_CLOSE_IF_OPEN(iTimer);
00033 }
00034 
00035 #define iLogDb ac_LogDb(iAppContext)
00036 #define iTelephony ac_Telephony(iAppContext)
00037 
00038 gboolean CSensor_indicator::StartL(GError** error)
00039 {
00040   iNumScanFailures = 0;
00041   if (!IsActive()) {
00042     MakeRequest();
00043     //log_db_log_status(iLogDb, NULL, "indicator sensor started");
00044   }
00045   return TRUE;
00046 }
00047 
00048 void CSensor_indicator::Stop()
00049 {
00050   if ((IsActive())) {
00051     Cancel();
00052     //log_db_log_status(iLogDb, NULL, "indicator sensor stopped");
00053   }
00054 }
00055 
00056 void CSensor_indicator::MakeRequest()
00057 {
00058   iTelephony.NotifyChange(iStatus, CTelephony::EIndicatorChange, iIndicatorDes);
00059   SetActive();
00060   iState = EQuerying;
00061   //logt("indicator sensor observing indicator");
00062 }
00063 
00064 void CSensor_indicator::SetTimer() 
00065 {
00066   int secs = 5 * (1 + iNumScanFailures) + (rand() % 10);
00067   TTimeIntervalMicroSeconds32 interval = SecsToUsecs(secs);
00068   logg("indicator timer set to %d secs / %d usecs", secs, interval.Int());
00069   iTimer.After(iStatus, interval);
00070   SetActive();
00071   iState = ERetryWaiting;
00072 }
00073 
00074 // Retry timer expired.
00075 void CSensor_indicator::HandleTimer()
00076 {
00077   int errCode = iStatus.Int();
00078   if (errCode) {
00079     // unexpected with an interval timer
00080     er_log_symbian(er_FATAL, errCode, "retry timer error in indicator");
00081     return;
00082   }
00083   MakeRequest();
00084 }
00085 
00086 static char ind2ch(CTelephony::TPhoneIndicators t,
00087        CTelephony::TIndicatorV1 d)
00088 {
00089   if ((d.iCapabilities & t) == 0)
00090     return 'N';
00091   if ((d.iIndicator & t) == 0)
00092     return '0';
00093   return '1';
00094 }
00095 
00096 #define IND2CH(t) (ind2ch(t, iIndicator))
00097 
00098 #define INDICATOR_EQ(x,y) \
00099   (((x).iIndicator == (y).iIndicator) && \
00100    ((x).iCapabilities == (y).iCapabilities))
00101 
00102 void CSensor_indicator::HandleRead()
00103 {
00104   int errCode = iStatus.Int();
00105 
00106   LogDb* logDb = ac_LogDb(iAppContext);
00107   GError* localError = NULL;
00108 
00109   if (errCode) {
00110     iNumScanFailures++;
00111     logg("%dth consecutive failure in indicator", iNumScanFailures);
00112 
00113     if (iNumScanFailures < 100) {
00114       dblogg("ERROR: %dth consecutive failure reading indicator sensor: %s (%d)", 
00115        iNumScanFailures, plat_error_strerror(errCode), errCode);
00116 
00117       SetTimer();
00118     } else {
00119       log_db_log_status(logDb, NULL, "INACTIVATE: indicator: stopping indicator scanning due to too many consecutive errors");
00120     }
00121 
00122     return;
00123   }
00124 
00125   {
00126     iNumScanFailures = 0;
00127 
00128     if (!(INDICATOR_EQ(iIndicator, iOldIndicator))) {
00129 #if 0
00130       logg("new indicator value: %u/%u", 
00131      iIndicator.iIndicator,
00132      iIndicator.iCapabilities);
00133 #endif
00134       guilogf("indicator: ac=%c nw=%c call=%c", 
00135         IND2CH(CTelephony::KIndChargerConnected),
00136         IND2CH(CTelephony::KIndNetworkAvailable),
00137         IND2CH(CTelephony::KIndCallInProgress));
00138 
00139       if (!log_db_log_indicator(logDb, iIndicator.iIndicator, 
00140         iIndicator.iCapabilities,
00141         &localError)) {
00142   gx_txtlog_fatal_error_free(localError);
00143   return;
00144       }
00145       
00146       iOldIndicator = iIndicator;
00147     }
00148 
00149     MakeRequest();
00150   }
00151 }
00152 
00153 void CSensor_indicator::RunL()
00154 {
00155   //logt("CSensor_indicator::RunL()");
00156 
00157   TState oldState = iState;
00158   iState = EInactive;
00159 
00160   switch (oldState)
00161     {
00162     case EQuerying:
00163       {
00164   HandleRead();
00165   break;
00166       }
00167     case ERetryWaiting:
00168       {
00169   HandleTimer();
00170         break;
00171       }
00172     default:
00173       {
00174         assert(0 && "unexpected state");
00175         break;
00176       }
00177     }
00178 }
00179 
00180 void CSensor_indicator::DoCancel()
00181 {
00182   switch (iState)
00183     {
00184     case EQuerying:
00185       {
00186   iTelephony.CancelAsync(CTelephony::EIndicatorChangeCancel);
00187         break;
00188       }
00189     case ERetryWaiting:
00190       {
00191   iTimer.Cancel();
00192         break;
00193       }
00194     default:
00195       {
00196         assert(0 && "unexpected state");
00197         break;
00198       }
00199     }
00200 
00201   // Note that the state must never become anything else without
00202   // invoking SetActive at the same time.
00203   iState = EInactive;
00204 }
00205 
00206 #endif // __INDICATOR_ENABLED__
00207 
00208 /**
00209 
00210 epoc-indicator.cpp
00211 
00212 Copyright 2009 Helsinki Institute for Information Technology (HIIT)
00213 and the authors. All rights reserved.
00214 
00215 Authors: Tero Hasu <tero.hasu@hut.fi>
00216 
00217 Permission is hereby granted, free of charge, to any person
00218 obtaining a copy of this software and associated documentation files
00219 (the "Software"), to deal in the Software without restriction,
00220 including without limitation the rights to use, copy, modify, merge,
00221 publish, distribute, sublicense, and/or sell copies of the Software,
00222 and to permit persons to whom the Software is furnished to do so,
00223 subject to the following conditions:
00224 
00225 The above copyright notice and this permission notice shall be
00226 included in all copies or substantial portions of the Software.
00227 
00228 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00229 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00230 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00231 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
00232 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
00233 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00234 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
00235 SOFTWARE.
00236 
00237  **/

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