00001 #include "up_private.h" 00002 00003 #if __FEATURE_UPLOADER__ 00004 00005 #include "up_poster_epoc.hpp" 00006 00007 #include "ac_app_context.h" 00008 #include "cf_query.h" 00009 #include "epoc-iap.h" 00010 #include "er_errors.h" 00011 #include "ld_log_db.h" 00012 #include "timer_generic_epoc.h" 00013 #include "ut_immediate_epoc.hpp" 00014 #include "utils_cl2.h" 00015 00016 #include "moment_parser.h" 00017 00018 #include "common/assertions.h" 00019 #include "common/epoc-time.h" 00020 #include "common/error_list.h" 00021 #include "common/logging-stack.h" 00022 #include "common/logging-time.h" 00023 #include "common/logging.h" 00024 #include "common/platform_error.h" 00025 00026 #include <e32base.h> 00027 #include <e32std.h> 00028 #include <utf.h> 00029 00030 #include <errno.h> 00031 #include <stdlib.h> 00032 #include <stdio.h> 00033 00034 // -------------------------------------------------- 00035 // controller class 00036 // -------------------------------------------------- 00037 00038 /***koog 00039 (require codegen/symbian-cxx) 00040 (ctor-defines/spec 00041 "CUploader" ;; name 00042 "LogDb* aLogDb" ;; args 00043 "iLogDb(aLogDb)" ;; inits 00044 "" ;; ctor 00045 #t ;; ConstructL 00046 ) 00047 ***/ 00048 #define CTOR_DECL_CUploader \ 00049 public: static CUploader* NewLC(LogDb* aLogDb); \ 00050 public: static CUploader* NewL(LogDb* aLogDb); \ 00051 private: CUploader(LogDb* aLogDb); \ 00052 private: void ConstructL(); 00053 00054 #define CTOR_IMPL_CUploader \ 00055 CUploader* CUploader::NewLC(LogDb* aLogDb) \ 00056 { \ 00057 CUploader* obj = new (ELeave) CUploader(aLogDb); \ 00058 CleanupStack::PushL(obj); \ 00059 obj->ConstructL(); \ 00060 return obj; \ 00061 } \ 00062 \ 00063 CUploader* CUploader::NewL(LogDb* aLogDb) \ 00064 { \ 00065 CUploader* obj = CUploader::NewLC(aLogDb); \ 00066 CleanupStack::Pop(obj); \ 00067 return obj; \ 00068 } \ 00069 \ 00070 CUploader::CUploader(LogDb* aLogDb) : iLogDb(aLogDb) \ 00071 {} 00072 /***end***/ 00073 00074 // Controls a timer AO (based on RTimer) and a "poster" AO (based on 00075 // RHTTPSession). Our goal here is to have enough state that we can at 00076 // any given time inspect that state and decide what to do next. There 00077 // are essentially two strands of execution as well, one for the 00078 // snapshot timing, and one for the upload control. 00079 // 00080 // Initially, we start the snapshot timer if there is any future time. 00081 // When the time is reached, we flag it as reached. Whenever a 00082 // snapshot is actually taken, we clear the reached flag, and set a 00083 // new timer as appropriate. The snapshot reached flag is also marked 00084 // when explicitly requested via the API. 00085 // 00086 // Initially, we also check if there are any old files. If so, we keep 00087 // uploading them one by one until exhausted. We set the no more old 00088 // files flag at that point. If an upload fails, we wait for a bit 00089 // before a retry. When there are no more old files, we only do 00090 // uploads after a snapshot has been taken. A snapshot is never taken 00091 // while there are old files remaining. 00092 NONSHARABLE_CLASS(CUploader) : 00093 public CBase, 00094 public MTimerObserver, 00095 public MPosterObserver, 00096 public MImmediateObserver 00097 { 00098 CTOR_DECL_CUploader; 00099 00100 public: 00101 ~CUploader(); 00102 00103 void RefreshIap(TBool aNotInitial); 00104 void RefreshSnapshotTimeExpr(TBool aNotInitial); 00105 00106 void RequestSnapshot(); 00107 00108 private: // MTimerObserver 00109 void HandleTimerEvent(CTimerAo* aTimerAo, TInt errCode); 00110 00111 private: // MPosterObserver 00112 void PosterEvent(TInt anError); 00113 00114 private: // MImmediateObserver 00115 void HandleImmediateEvent(); 00116 00117 private: // property 00118 00119 LogDb* iLogDb; // not owned 00120 00121 TBool iNotReady; // no upload URL 00122 TPtrC8 iUploadUrl; // data not owned 00123 TUint32 iIapId; 00124 00125 //// posting state 00126 CPosterAo* iPosterAo; 00127 CTimerAo* iPostTimerAo; 00128 gchar* iFileToPost; // pathname of file to upload 00129 TBool iNoOldFiles; // getNextOldLogFile found nothing 00130 TInt iNumPostFailures; // affects retry timing 00131 CImmediateAo* iImmediateAo; 00132 00133 //// snapshot taking state 00134 CTimerAo* iSnapshotTimerAo; 00135 TBool iSnapshotTimePassed; 00136 gchar* iSnapshotTimeExpr; 00137 time_t iSnapshotTimeCtx; 00138 TBool iNoNextSnapshotTime; 00139 00140 //// blackboard 00141 public: 00142 void Set_uploads_allowed(TBool val); 00143 private: 00144 TBool i_uploads_allowed; // from blackboard 00145 bb_Closure iClosure; 00146 void BbRegisterL(); 00147 void BbUnregister(); 00148 00149 private: // methods 00150 void Inactivate(); 00151 void InactivateLater(); 00152 void StateChanged(); 00153 void StateChangedL(); 00154 void StateChangedLater(); 00155 void NextOldFileL(); 00156 TInt CreatePosterAo(); 00157 void DestroyPosterAo(); 00158 TBool PosterAoIsActive() { return (iPosterAo && iPosterAo->IsActive()); } 00159 void HandleCommsError(TInt errCode); 00160 void PostNowL(); 00161 void SetPostRetryTimer(); 00162 void SetSnapshotTimerL(); 00163 void TakeSnapshotNowL(); 00164 void FatalError(TInt anError); 00165 00166 }; 00167 00168 CTOR_IMPL_CUploader; 00169 00170 static void DataChanged(bb_Blackboard* bb, enum bb_DataType dt, 00171 gpointer data, int len, gpointer arg) 00172 { 00173 (void)dt; 00174 (void)len; 00175 CUploader* self = (CUploader*)arg; 00176 bb_Board* bd = bb_Blackboard_board(bb); 00177 TBool val = bd->uploads_allowed; 00178 self->Set_uploads_allowed(val); 00179 } 00180 00181 void CUploader::Set_uploads_allowed(TBool val) 00182 { 00183 i_uploads_allowed = val; 00184 StateChanged(); 00185 } 00186 00187 void CUploader::BbRegisterL() 00188 { 00189 // Initial value (internal). 00190 bb_Blackboard* bb = ac_global_Blackboard; 00191 bb_Board* bd = bb_Blackboard_board(bb); 00192 i_uploads_allowed = bd->uploads_allowed; 00193 00194 // Closure init. 00195 iClosure.changed = DataChanged; 00196 iClosure.arg = this; 00197 00198 // Registration proper. 00199 if (!bb_Blackboard_register(bb, 00200 bb_dt_uploads_allowed, 00201 iClosure, NULL)) 00202 User::LeaveNoMemory(); 00203 } 00204 00205 void CUploader::BbUnregister() 00206 { 00207 bb_Blackboard_unregister(ac_global_Blackboard, iClosure); 00208 } 00209 00210 // The effect is not immediate. Will only take effect when the next 00211 // poster is created. 00212 // 00213 // We do logging here to make it possible to find out if the setting 00214 // change succeeded. 00215 void CUploader::RefreshIap(TBool aNotInitial) 00216 { 00217 // TUint32 coercion hopefully okay. 00218 iIapId = (TUint32)get_config_iap_id(); 00219 if (aNotInitial) 00220 log_db_log_status(iLogDb, NULL, "Uploader IAP changed to %d", iIapId); 00221 } 00222 00223 void CUploader::RefreshSnapshotTimeExpr(TBool aNotInitial) 00224 { 00225 GError* localError = NULL; 00226 gchar* newOne = NULL; 00227 if (!get_ConfigDb_str("uploader.time_expr", 00228 &newOne, __UPLOAD_TIME_EXPR__, 00229 &localError)) { 00230 if (aNotInitial) 00231 gx_dblog_error_free_check(iLogDb, localError, NULL); 00232 else 00233 gx_error_free(localError); 00234 } else { 00235 assert(newOne != NULL); 00236 g_free(iSnapshotTimeExpr); 00237 iSnapshotTimeExpr = newOne; 00238 logt("got time expression"); 00239 logt(iSnapshotTimeExpr); 00240 if (aNotInitial) { 00241 log_db_log_status(iLogDb, NULL, "Upload time expression set to '%s'", 00242 newOne); 00243 00244 // We may need to recompute the next snapshot time based on the 00245 // new expression. But if a previosly set time has already 00246 // passed, then that is not affected by the expression change. 00247 // What is past is past. 00248 { 00249 iSnapshotTimerAo->Cancel(); 00250 iNoNextSnapshotTime = EFalse; 00251 StateChanged(); 00252 } 00253 } 00254 } 00255 } 00256 00257 void CUploader::ConstructL() 00258 { 00259 const gchar* upload_url = ac_STATIC_GET(upload_url); 00260 if (!upload_url) { 00261 iNotReady = ETrue; 00262 logt("uploads disabled: no upload URL"); 00263 } else { 00264 iUploadUrl.Set((TUint8*)upload_url, strlen(upload_url)); 00265 logg("upload URL: %s", upload_url); 00266 } 00267 00268 RefreshIap(EFalse); 00269 logg("uploader using IAP %d", iIapId); 00270 00271 // Ensure that uploads directory exists. 00272 GError* mdError = NULL; 00273 if (!mkdir_p(LOG_UPLOADS_DIR, &mdError)) { 00274 gx_txtlog_error_free(mdError); 00275 User::Leave(KErrGeneral); 00276 } 00277 00278 iImmediateAo = CImmediateAo::NewL(*this); 00279 iPostTimerAo = CTimerAo::NewL(*this, CActive::EPriorityStandard); 00280 iSnapshotTimerAo = CTimerAo::NewL(*this, CActive::EPriorityStandard); 00281 RefreshSnapshotTimeExpr(EFalse); 00282 iSnapshotTimeCtx = time(NULL); //xxx needs to come from ConfigDb -- but actually ones the next time is computed by a Lua expression, that expression can contain any required fixpoint as a constant 00283 if (iSnapshotTimeCtx == -1) User::Leave(KErrGeneral); 00284 //logg("using snapshot time '%s'", iSnapshotTimeExpr); 00285 00286 // Note that if this ConstructL() leaves, the dtor of this will 00287 // unregister us. 00288 BbRegisterL(); 00289 00290 StateChangedL(); 00291 } 00292 00293 CUploader::~CUploader() 00294 { 00295 Inactivate(); 00296 delete iPostTimerAo; 00297 delete iSnapshotTimerAo; 00298 delete iImmediateAo; 00299 g_free(iFileToPost); // safe when NULL 00300 g_free(iSnapshotTimeExpr); // safe when NULL 00301 } 00302 00303 void CUploader::StateChangedLater() 00304 { 00305 if (!iImmediateAo->IsActive()) { 00306 iImmediateAo->Complete(); 00307 } 00308 } 00309 00310 void CUploader::Inactivate() 00311 { 00312 logh(); 00313 if (iSnapshotTimerAo) iSnapshotTimerAo->Cancel(); 00314 if (iPostTimerAo) iPostTimerAo->Cancel(); 00315 if (iImmediateAo) iImmediateAo->Cancel(); 00316 iNotReady = ETrue; 00317 DestroyPosterAo(); 00318 BbUnregister(); 00319 } 00320 00321 void CUploader::InactivateLater() 00322 { 00323 logh(); 00324 if (iSnapshotTimerAo) iSnapshotTimerAo->Cancel(); 00325 if (iPostTimerAo) iPostTimerAo->Cancel(); 00326 iNotReady = ETrue; 00327 StateChangedLater(); 00328 } 00329 00330 void CUploader::FatalError(TInt errCode) 00331 { 00332 er_log_symbian(er_FATAL, errCode, "in uploader"); 00333 } 00334 00335 void CUploader::StateChanged() 00336 { 00337 TRAPD(errCode, StateChangedL()); 00338 if (errCode) 00339 FatalError(errCode); 00340 } 00341 00342 void CUploader::NextOldFileL() 00343 { 00344 if (iNoOldFiles) return; 00345 00346 g_free(iFileToPost); // safe when NULL 00347 iFileToPost = NULL; 00348 00349 GError* error = NULL; 00350 if (getNextOldLogFile(&iFileToPost, &error)) { 00351 if (iFileToPost) { 00352 return; 00353 } else { 00354 iNoOldFiles = ETrue; 00355 dblogt("no more old files to upload"); 00356 } 00357 } else { 00358 er_log_gerror(er_FATAL|er_FREE, error, "getting next log file"); 00359 } 00360 } 00361 00362 // External API. 00363 void CUploader::RequestSnapshot() 00364 { 00365 iSnapshotTimePassed = ETrue; 00366 iSnapshotTimerAo->Cancel(); 00367 StateChanged(); 00368 } 00369 00370 // Computes next snapshot time (if any), and sets a timer for it as 00371 // appropriate. 00372 void CUploader::SetSnapshotTimerL() 00373 { 00374 assert(!iSnapshotTimePassed); 00375 iSnapshotTimerAo->Cancel(); 00376 if (iNoNextSnapshotTime) return; // flag to avoid needless computation 00377 time_t now = time(NULL); 00378 if (now == -1) 00379 User::Leave(KErrGeneral); 00380 time_t ctx = iSnapshotTimeCtx; 00381 time_t snaptime; 00382 GError* parseError = NULL; 00383 if (!parse_moment(iSnapshotTimeExpr, ctx, now, &snaptime, &parseError)) { 00384 gx_txtlog_error_free(parseError); 00385 iNoNextSnapshotTime = ETrue; 00386 return; 00387 } 00388 if (!snaptime) { 00389 dblogt("no snapshot time upcoming"); 00390 iNoNextSnapshotTime = ETrue; 00391 return; 00392 } 00393 logt("next snapshot time computed"); 00394 log_time(snaptime); 00395 // Note that RTimer At and AtUTC often return with a KErrAbort in 00396 // current phones. Still, here we definitely want to be using 00397 // absolute times. http://www.newlc.com/en/topic-5076 00398 // http://wiki.forum.nokia.com/index.php/TSS000261_-_Timer_issues_and_tips 00399 TTime epocTime; 00400 #if 1 00401 UnixTimeToUtcEpocTime(epocTime, snaptime); 00402 iSnapshotTimerAo->AtUTC(epocTime); 00403 #else 00404 UnixTimeToLocalEpocTime(epocTime, snaptime); 00405 iSnapshotTimerAo->At(epocTime); 00406 #endif 00407 } 00408 00409 void CUploader::SetPostRetryTimer() 00410 { 00411 assert(iNumPostFailures > 0); 00412 00413 iPostTimerAo->Cancel(); 00414 00415 // Roughly num_failures * 5 mins. xxx perhaps this should be computed by a Lua function coming from ConfigDb 00416 int secs = 5 * 60 * iNumPostFailures + (rand() % 60); 00417 TTimeIntervalMicroSeconds32 interval = SecsToUsecs(secs); 00418 dblogg("retrying upload in %d secs / %d usecs", secs, interval.Int()); 00419 00420 // Note that these timers should not complete with KErrAbort, since 00421 // a wait for an interval should not be affected by a system time 00422 // change. 00423 iPostTimerAo->After(interval); 00424 } 00425 00426 // Make sure this method does not leave. 00427 void CUploader::HandleTimerEvent(CTimerAo* aTimerAo, TInt errCode) 00428 { 00429 logg("timer event (%d)", errCode); 00430 00431 if (errCode == KErrAbort) { 00432 // System time changed. We should recompute the snapshot time, as 00433 // this may not be just a time zone change, but also the UTC time 00434 // may have been changed. Normally though the changes are trivial, 00435 // and frequent changes are often caused by network-based time 00436 // updates. 00437 logt("system time changed"); 00438 assert(aTimerAo == iSnapshotTimerAo); // should be only for At timers 00439 iNoNextSnapshotTime = EFalse; // not sure of this anymore 00440 StateChanged(); // go recompute the time and set the timer again 00441 return; 00442 } 00443 00444 if (errCode == KErrUnderflow) { 00445 // This is quite possible. We might compute a time that is a 00446 // fraction of a second later, and by the time we got to asking 00447 // for a timer event the time might have just passed. This is 00448 // okay. 00449 assert(aTimerAo == iSnapshotTimerAo); // our After intervals should not be negative 00450 logt("expiration time in the past"); 00451 errCode = KErrNone; 00452 } 00453 00454 if (errCode) { 00455 FatalError(errCode); 00456 } else if (aTimerAo == iPostTimerAo) { 00457 logt("was posting timer"); 00458 StateChanged(); 00459 } else if (aTimerAo == iSnapshotTimerAo) { 00460 logt("was snapshot timer"); 00461 iSnapshotTimePassed = ETrue; 00462 StateChanged(); 00463 } else { 00464 assert(0); 00465 } 00466 } 00467 00468 void CUploader::HandleImmediateEvent() 00469 { 00470 logh(); 00471 StateChanged(); 00472 } 00473 00474 // Happens in a callback always. 00475 void CUploader::PosterEvent(TInt anError) 00476 { 00477 dblogg("poster reports %d", anError); 00478 00479 switch (anError) 00480 { 00481 case POSTER_SUCCESS: 00482 { 00483 GError* localError = NULL; 00484 //assert(iFileToPost); 00485 //logg("removing file '%s'", iFileToPost); 00486 if (!rm_file(iFileToPost, &localError)) { 00487 //logt("failure removing file"); 00488 gx_txtlog_error_free(localError); 00489 FatalError(KErrGeneral); 00490 } else { 00491 log_db_log_status(iLogDb, NULL, "posted log file '%s'", iFileToPost); 00492 iNumPostFailures = 0; 00493 g_free(iFileToPost); 00494 iFileToPost = NULL; 00495 00496 { 00497 time_t t = time(NULL); 00498 if (t == -1) { 00499 er_log_errno(er_FATAL, "time()"); 00500 return; 00501 } 00502 ac_global_Registry->last_upload_time = t; 00503 } 00504 00505 StateChangedLater(); 00506 } 00507 break; 00508 } 00509 case POSTER_TRANSIENT_FAILURE: 00510 { 00511 // Retry later. 00512 iNumPostFailures++; 00513 SetPostRetryTimer(); 00514 StateChangedLater(); // to destroy poster AO 00515 break; 00516 } 00517 case POSTER_PERMANENT_FAILURE: 00518 { 00519 // We must be doing something wrong. Better stop altogether, 00520 // barring external intervention. 00521 er_log_none(0, "inactivating uploader due to a permanent posting failure"); 00522 InactivateLater(); 00523 break; 00524 } 00525 default: // Symbian error 00526 { 00527 assert(anError < 0); 00528 HandleCommsError(anError); 00529 break; 00530 } 00531 } 00532 } 00533 00534 // Called to handle poster creation and poster request errors. May or 00535 // may not happen in a callback. 00536 void CUploader::HandleCommsError(TInt anError) 00537 { 00538 // Some errors are more severe than others. 00539 switch (anError) 00540 { 00541 // Some errors warrant the recreation of iPosterAo (if we even 00542 // have one). 00543 case KErrCouldNotConnect: 00544 case KErrDisconnected: 00545 case KErrCommsLineFail: 00546 case KErrCommsFrame: 00547 case KErrCommsOverrun: 00548 case KErrCommsParity: 00549 case KErrInUse: // file in use maybe 00550 case KErrNotReady: // -18 ("A device required by an I/O operation is not ready to start operations.") We have actually gotten this error. Let us have it here to see if it is something transient. 00551 case KErrServerBusy: // local daemon, such as socket or file server 00552 case KErrTimedOut: // (very often see this error) 00553 case -5120: // no response from DNS server (often see this error) 00554 case -8268: // not documented, but getting this in flight mode 00555 case -30180: // not documented, getting this when WLAN specified in IAP is not within range 00556 { 00557 // Retry later. 00558 iNumPostFailures++; 00559 SetPostRetryTimer(); 00560 StateChangedLater(); // to destroy poster AO 00561 break; 00562 } 00563 00564 // Some errors are considered fatal. 00565 case KErrNoMemory: // bad, resume this program later 00566 case KErrPathNotFound: // our state may be messed up 00567 { 00568 FatalError(anError); 00569 break; 00570 } 00571 00572 // Some errors are considered permanently fatal. In such cases 00573 // the situation likely will not improve by restarting the 00574 // process. 00575 case KErrNotSupported: // perhaps uploader cannot function on this device 00576 case KErrNotFound: // some required resource missing perhaps 00577 default: 00578 { 00579 // We do not yet have logic for handling this kind of 00580 // error, so inactivate. Future versions may implement 00581 // this better. 00582 dblogg("inactivating uploader due to Symbian error %d", anError); 00583 InactivateLater(); 00584 break; 00585 } 00586 } // end switch 00587 } 00588 00589 void CUploader::StateChangedL() 00590 { 00591 if (iNotReady) { 00592 Inactivate(); 00593 return; 00594 } 00595 00596 if (!PosterAoIsActive()) { 00597 DestroyPosterAo(); // make sure no connection remains 00598 } 00599 00600 if (!iSnapshotTimePassed && 00601 !iNoNextSnapshotTime && 00602 !iSnapshotTimerAo->IsActive()) { 00603 SetSnapshotTimerL(); 00604 } 00605 00606 again: 00607 if (iFileToPost) { 00608 if (PosterAoIsActive() || 00609 // 'iPostTimerAo' is a post retry timer. 00610 iPostTimerAo->IsActive()) 00611 return; 00612 if (i_uploads_allowed) { 00613 PostNowL(); // not called elsewhere 00614 } 00615 } else if (!iNoOldFiles) { 00616 NextOldFileL(); 00617 goto again; 00618 } else if (iSnapshotTimePassed) { 00619 TakeSnapshotNowL(); // not called elsewhere 00620 } 00621 } 00622 00623 TInt CUploader::CreatePosterAo() 00624 { 00625 assert(!iPosterAo); 00626 00627 TRAPD(errCode, iPosterAo = CPosterAo::NewL(*this, iIapId)); 00628 if (errCode) { 00629 logg("poster creation failed with %d", errCode); 00630 } 00631 00632 return errCode; 00633 } 00634 00635 void CUploader::DestroyPosterAo() 00636 { 00637 if (iPosterAo) { 00638 delete iPosterAo; 00639 iPosterAo = NULL; 00640 logt("poster destroyed"); 00641 } 00642 } 00643 00644 void CUploader::PostNowL() 00645 { 00646 // For error handling testing. 00647 #if 0 00648 logt("horrible test error"); 00649 User::Leave(KErrTotalLossOfPrecision); 00650 #endif 00651 00652 logt("trying to post file now"); 00653 00654 if (!iPosterAo) { 00655 logt("creating poster"); 00656 TInt errCode = CreatePosterAo(); 00657 if (errCode) { 00658 logg("failure creating poster %d", errCode); 00659 HandleCommsError(errCode); 00660 return; 00661 } 00662 } 00663 00664 TPtrC8 fileName((TUint8*)iFileToPost); 00665 TFileName fileNameDes; 00666 // Our names should all be ASCII, so this may be overkill. 00667 User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(fileNameDes, fileName)); 00668 dblogg("asking poster to post '%s'", iFileToPost); 00669 iPosterAo->PostFileL(iUploadUrl, fileNameDes); 00670 } 00671 00672 void CUploader::TakeSnapshotNowL() 00673 { 00674 dblogt("taking snapshot now"); 00675 00676 // LOG_UPLOADS_DIR and LOGDB_DIR must be on the same device to allow 00677 // for renaming rather than copying. 00678 char* pathname = tempnam(LOG_UPLOADS_DIR, "log_"); // caller must free 'pathname' 00679 if (!pathname) { 00680 er_log_errno(er_FATAL, "failure in tempnam"); 00681 } 00682 00683 gboolean wasRenamed = FALSE; 00684 GError* snapError = NULL; 00685 if (!log_db_take_snapshot(iLogDb, pathname, &wasRenamed, &snapError)) { 00686 logg("failure taking snapshot to file '%s'", pathname); 00687 free(pathname); 00688 logg("snapshot file was%s created", wasRenamed ? "" : " not"); 00689 er_log_gerror(er_FATAL|er_FREE, snapError, "taking snapshot"); 00690 } 00691 00692 log_db_log_status(iLogDb, NULL, "snapshot taken as '%s'", pathname); 00693 00694 assert(!iFileToPost); 00695 iFileToPost = pathname; 00696 iSnapshotTimePassed = EFalse; 00697 StateChangedL(); 00698 } 00699 00700 // -------------------------------------------------- 00701 // global system state 00702 // -------------------------------------------------- 00703 00704 EXTERN_C gboolean up_global_init(GError** error) 00705 { 00706 // Nothing to do. 00707 return TRUE; 00708 } 00709 00710 EXTERN_C void up_global_cleanup() 00711 { 00712 // Nothing to do. 00713 } 00714 00715 // -------------------------------------------------- 00716 // API 00717 // -------------------------------------------------- 00718 00719 EXTERN_C gboolean up_Uploader_upload_now(up_Uploader* object, GError** error) 00720 { 00721 ((CUploader*)object)->RequestSnapshot(); 00722 return TRUE; 00723 } 00724 00725 EXTERN_C gboolean up_Uploader_reconfigure(up_Uploader* object, 00726 const gchar* key, 00727 const gchar* value, 00728 GError** error) 00729 { 00730 if (strcmp(key, "iap") == 0) { 00731 ((CUploader*)object)->RefreshIap(ETrue); 00732 } else if (strcmp(key, "uploader.time_expr") == 0) { 00733 ((CUploader*)object)->RefreshSnapshotTimeExpr(ETrue); 00734 } 00735 return TRUE; 00736 } 00737 00738 EXTERN_C up_Uploader* up_Uploader_new(ac_AppContext* aAppContext, GError** error) 00739 { 00740 CUploader* object = NULL; 00741 TRAPD(errCode, object = CUploader::NewL(ac_LogDb(aAppContext))); 00742 if (errCode) { 00743 if (error) 00744 *error = gx_error_new(domain_symbian, errCode, "Uploader init failure: %s (%d)", plat_error_strerror(errCode), errCode); 00745 return NULL; 00746 } 00747 return (up_Uploader*)object; 00748 } 00749 00750 EXTERN_C void up_Uploader_destroy(up_Uploader* object) 00751 { 00752 delete ((CUploader*)object); 00753 } 00754 00755 #endif // __FEATURE_UPLOADER__ 00756 00757 /** 00758 00759 up_uploader_epoc.cpp 00760 00761 Copyright 2009 Helsinki Institute for Information Technology (HIIT) 00762 and the authors. All rights reserved. 00763 00764 Authors: Tero Hasu <tero.hasu@hut.fi> 00765 00766 Permission is hereby granted, free of charge, to any person 00767 obtaining a copy of this software and associated documentation files 00768 (the "Software"), to deal in the Software without restriction, 00769 including without limitation the rights to use, copy, modify, merge, 00770 publish, distribute, sublicense, and/or sell copies of the Software, 00771 and to permit persons to whom the Software is furnished to do so, 00772 subject to the following conditions: 00773 00774 The above copyright notice and this permission notice shall be 00775 included in all copies or substantial portions of the Software. 00776 00777 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00778 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00779 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00780 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 00781 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 00782 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00783 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00784 SOFTWARE. 00785 00786 **/
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:56 2011 by Doxygen 1.6.1