|
1 /* |
|
2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0"" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: CMMCScBkupWriteDataTransferRequestBase implementation |
|
15 * |
|
16 * |
|
17 */ |
|
18 |
|
19 #include "CMMCScBkupTransferWriteRequest.h" |
|
20 |
|
21 // User includes |
|
22 #include "MMCScBkupLogger.h" |
|
23 #include "MMMCScBkupDriver.h" |
|
24 #include "CMMCScBkupArchive.h" |
|
25 #include "MMCScBkupSBEUtils.h" |
|
26 #include "RMMCScBkupProgressSizer.h" |
|
27 #include "MMMCScBkupProgressObserver.h" |
|
28 #include "MMMCScBkupArchiveDataInterface.h" |
|
29 #include "CMMCScBkupDriveAndOperationTypeManager.h" |
|
30 #include <pathinfo.h> |
|
31 |
|
32 |
|
33 |
|
34 #ifdef __MMCSCBKUP_DATA_LOGGING_ENABLED__ |
|
35 |
|
36 static void __DebugDump( const TDesC& aFmt, const TUint8* aAddress, const TUint8* aDisplayStartAddress, TInt aLength, TInt aMaxLength) |
|
37 { |
|
38 const TInt maxLen = aMaxLength; |
|
39 TInt len = aLength; |
|
40 const TUint8* pDataAddr = aAddress; |
|
41 |
|
42 TBuf<81> out; |
|
43 TBuf<20> ascii; |
|
44 TInt offset = 0; |
|
45 const TUint8* a = pDataAddr; |
|
46 const TUint8* displayAddress = aDisplayStartAddress; |
|
47 // |
|
48 while(len>0) |
|
49 { |
|
50 out.Zero(); |
|
51 ascii.Zero(); |
|
52 out.AppendNumFixedWidth((TUint) displayAddress, EHex, 8); |
|
53 out.Append(_L(": ")); |
|
54 |
|
55 TUint b; |
|
56 for (b=0; b<16; b++) |
|
57 { |
|
58 TUint8 c = ' '; |
|
59 if ((pDataAddr + offset + b) < pDataAddr + maxLen) |
|
60 { |
|
61 c = *(pDataAddr + offset + b); |
|
62 out.AppendNumFixedWidth(c, EHex, 2); |
|
63 } |
|
64 else |
|
65 { |
|
66 out.Append(_L(" ")); |
|
67 } |
|
68 out.Append(' '); |
|
69 if (c<=0x20 || c>=0x7f || c=='%') |
|
70 c=0x2e; |
|
71 ascii.Append(TChar(c)); |
|
72 } |
|
73 out.Append(ascii); |
|
74 out.ZeroTerminate(); |
|
75 |
|
76 RDebug::Print(aFmt, &out); |
|
77 |
|
78 displayAddress += 16; |
|
79 a += 16; |
|
80 offset += 16; |
|
81 len -= 16; |
|
82 } |
|
83 } |
|
84 |
|
85 #endif |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 // ========================= MEMBER FUNCTIONS ================================ |
|
93 |
|
94 // --------------------------------------------------------------------------- |
|
95 // CMMCScBkupWriteDataTransferRequestBase::CMMCScBkupWriteDataTransferRequestBase() |
|
96 // |
|
97 // C++ constructor. |
|
98 // --------------------------------------------------------------------------- |
|
99 CMMCScBkupWriteDataTransferRequestBase::CMMCScBkupWriteDataTransferRequestBase( |
|
100 MMMCScBkupDriver& aDriver, |
|
101 MMMCScBkupIndexHandler& aIndexHandler, |
|
102 TMMCScBkupOwnerDataType aElementType, |
|
103 TSBDerivedType aExpectedTransferType, |
|
104 TInt aPriority ) |
|
105 |
|
106 : CMMCScBkupTransferRequestBase( aDriver, aElementType, aPriority ), |
|
107 iIndexHandler( aIndexHandler ), |
|
108 iExpectedTransferType( aExpectedTransferType ) |
|
109 { |
|
110 } |
|
111 |
|
112 |
|
113 // --------------------------------------------------------------------------- |
|
114 // CMMCScBkupWriteDataTransferRequestBase::~CMMCScBkupWriteDataTransferRequestBase() |
|
115 // |
|
116 // Destructor. |
|
117 // --------------------------------------------------------------------------- |
|
118 CMMCScBkupWriteDataTransferRequestBase::~CMMCScBkupWriteDataTransferRequestBase() |
|
119 { |
|
120 delete iTransferType; |
|
121 if ( iStreamIsOpen ) |
|
122 { |
|
123 iStream.Close(); |
|
124 } |
|
125 } |
|
126 |
|
127 |
|
128 // --------------------------------------------------------------------------- |
|
129 // CMMCScBkupWriteDataTransferRequestBase::RequestL() |
|
130 // |
|
131 // |
|
132 // --------------------------------------------------------------------------- |
|
133 void CMMCScBkupWriteDataTransferRequestBase::RequestL( CMMCScBkupDataOwnerInfo& aOwner, TRequestStatus& aObserver, const CMMCScBkupDriveAndOperationTypeManager& aDriveAndOperations ) |
|
134 { |
|
135 #ifdef __MMCSCBKUPLOGGING_ENABLED__ |
|
136 if ( ElementType() == EMMCScBkupOwnerDataTypeJavaData ) |
|
137 { |
|
138 HBufC* hash = MMCScBkupSBEUtils::JavaHashFromGenericLC( aOwner.Owner().Identifier() ); |
|
139 __LOG2("CMMCScBkupWriteDataTransferRequestBase::RequestL() - START - reading data from SBE for JavaHash: %S, ElementType: %S", hash, &MMCScBkupLogger::DataType( ElementType() )); |
|
140 CleanupStack::PopAndDestroy( hash ); |
|
141 } |
|
142 else |
|
143 { |
|
144 __LOG2("CMMCScBkupWriteDataTransferRequestBase::RequestL() - START - reading data from SBE for DO: 0x%08x, ElementType: %S", aOwner.SecureId().iId, &MMCScBkupLogger::DataType( ElementType() )); |
|
145 } |
|
146 #endif |
|
147 |
|
148 iDriveAndOperations = &aDriveAndOperations; |
|
149 CMMCScBkupTransferRequestBase::RequestL( aOwner, aObserver ); |
|
150 // |
|
151 iDriveFilter.Reset(); |
|
152 iDriveFilter.SetPrimaryDriveFilter( iDriveAndOperations->DriveList() ); |
|
153 iDriveFilter.SetSecondaryDriveFilter( aOwner.Owner().DriveList() ); |
|
154 |
|
155 // Set us going |
|
156 SetState( ETransferData ); |
|
157 CompleteSelf(); |
|
158 __LOG("CMMCScBkupWriteDataTransferRequestBase::RequestL() - END"); |
|
159 } |
|
160 |
|
161 |
|
162 // --------------------------------------------------------------------------- |
|
163 // CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() |
|
164 // |
|
165 // |
|
166 // --------------------------------------------------------------------------- |
|
167 TBool CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() |
|
168 { |
|
169 MMMCScBkupDriver& driver = Driver(); |
|
170 MMMCScBkupArchiveDataInterface& archiveDataInterface = driver.DrvADI(); |
|
171 |
|
172 // Get a handle to the received data |
|
173 TBool finished = EFalse; |
|
174 CSBGenericTransferType* receivedTransferInfo = NULL; |
|
175 const TPtrC8& pData = driver.DrvSecureBackupClient().TransferDataInfoL( receivedTransferInfo, finished ); |
|
176 iAdditionalTransferRequired = !finished; |
|
177 |
|
178 __LOG4("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - received: %d bytes from SBE for SID: 0x%08x, Drive: %c:, ElementType: %S", pData.Length(), DataOwner().SecureId().iId, 'A' + CurrentDrive(), &MMCScBkupLogger::DataType( ElementType() ) ); |
|
179 |
|
180 // Validate the data |
|
181 CleanupStack::PushL( receivedTransferInfo ); |
|
182 ValidateTransferInfoL( receivedTransferInfo ); |
|
183 CleanupStack::PopAndDestroy( receivedTransferInfo ); |
|
184 |
|
185 // If we've never written any registration data before, then we must |
|
186 // request a write stream at the current archive write pos... |
|
187 if ( pData.Length() && !iStreamIsOpen ) |
|
188 { |
|
189 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - stream isnt open - opening now..." ); |
|
190 |
|
191 iStream = archiveDataInterface.ADIWriteStreamUncompressedLC(); |
|
192 CleanupStack::Pop(); // iWriteStream - gets closed in dtor in case of leave |
|
193 iStreamIsOpen = ETrue; |
|
194 } |
|
195 |
|
196 // Write the data - assumes stream already open if this is not the |
|
197 // first time that we've received data for this drive... |
|
198 // |
|
199 // We don't use the externalisation operators, as we want to write |
|
200 // only the data (no leading byte count etc). |
|
201 if ( pData.Length() ) |
|
202 { |
|
203 __LOG1("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - got %d bytes of data...", pData.Length() ); |
|
204 |
|
205 #ifdef __MMCSCBKUP_DATA_LOGGING_ENABLED__ |
|
206 _LIT(KDumpFormat, "SBEData - %S - "); |
|
207 __DebugDump( KDumpFormat, pData.Ptr(), pData.Ptr(), pData.Length(), pData.Length() ); |
|
208 #endif |
|
209 |
|
210 // Write the data to the stream |
|
211 __LOG1("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - writing %d bytes to stream...", pData.Length() ); |
|
212 iStream.WriteL(pData); |
|
213 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - data written OK"); |
|
214 |
|
215 // Update our stats. We overwrite any earlier estimate from the SBE |
|
216 // with the actual values that we ultimately end up writing to the |
|
217 // archive. This allows us to provide a more accurate restore progress |
|
218 // experience. |
|
219 DataTransferred( pData.Length() ); |
|
220 |
|
221 #ifdef DEBUGGING_DATA_TRANSFER |
|
222 TRAP_IGNORE( DumpTransferDataL( archiveDataInterface.ADIFsSession(), pData ) ); |
|
223 #endif |
|
224 } |
|
225 |
|
226 // If we've received everything we can commit & close the stream |
|
227 if ( finished ) |
|
228 { |
|
229 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - finished..."); |
|
230 |
|
231 // Implicitly, if the stream is open then we have written some |
|
232 // data to the archive. Therefore we only add an index record |
|
233 // when the stream is open. |
|
234 if ( iStreamIsOpen ) |
|
235 { |
|
236 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - Committing stream..."); |
|
237 iStream.CommitL(); |
|
238 |
|
239 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - Closing stream..."); |
|
240 iStream.Close(); |
|
241 iStreamIsOpen = EFalse; |
|
242 |
|
243 // Must store the position, as we're going to also write an index at |
|
244 // the end of this whole process. |
|
245 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - Adding index record..."); |
|
246 CMMCScBkupArchiveFooter& footer = driver.DrvArchive().Footer(); |
|
247 const TMMCScBkupArchiveVector& info = archiveDataInterface.ADICurrentArchiveVectorInfo(); |
|
248 |
|
249 // If we actually wrote something to the archive, then add an index record. |
|
250 if (info.Length()) |
|
251 { |
|
252 iIndexHandler.AddIndexRecordL( footer, DataOwner(), info, CurrentDrive() ); |
|
253 } |
|
254 } |
|
255 } |
|
256 |
|
257 // Not yet supporting chunked transfer |
|
258 __LOG("CMMCScBkupWriteDataTransferRequestBase::ProcessChunkOfDataL() - END"); |
|
259 return EFalse; |
|
260 } |
|
261 |
|
262 |
|
263 // --------------------------------------------------------------------------- |
|
264 // CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() |
|
265 // |
|
266 // |
|
267 // --------------------------------------------------------------------------- |
|
268 void CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() |
|
269 { |
|
270 // If we must make a repeat transfer request, then we don't yet |
|
271 // move to the next drive. |
|
272 if ( iAdditionalTransferRequired ) |
|
273 { |
|
274 // Must ask for more of the same data, so no need |
|
275 // to rebuild transfer info - we just reuse it |
|
276 RequestDataTransferL(); |
|
277 } |
|
278 else |
|
279 { |
|
280 // Can move to the next drive |
|
281 TDriveNumber drive = EDriveA; |
|
282 const TBool driveAvailable = iDriveFilter.NextValidDrive( drive ); |
|
283 __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - current drive: %c", drive + 'A'); |
|
284 __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - driveAvailable: %d", driveAvailable); |
|
285 |
|
286 if ( driveAvailable ) |
|
287 { |
|
288 const TBool dataTransferAllowableForDrive = iDriveAndOperations->IsDataTypeAllowedToAccessDrive( drive, ElementType() ); |
|
289 __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - dataTransferAllowableForDrive: %d", dataTransferAllowableForDrive); |
|
290 |
|
291 if ( dataTransferAllowableForDrive ) |
|
292 { |
|
293 __LOG1("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - making transfer request for drive: %c", drive + 'A'); |
|
294 |
|
295 // Update the current drive |
|
296 SetCurrentDrive( drive ); |
|
297 |
|
298 // Make virtual function call to make transfer object |
|
299 const CSBGenericDataType& generic = DataOwner().Owner().Identifier(); |
|
300 CSBGenericTransferType* transferType = PrepareTransferTypeL( generic, CurrentDrive(), DataOwner().Version() ); |
|
301 delete iTransferType; |
|
302 iTransferType = transferType; |
|
303 |
|
304 // We have a transfer packet, so now request data |
|
305 RequestDataTransferL(); |
|
306 } |
|
307 else |
|
308 { |
|
309 // Couldn't process this drive, let's try to find another drive. |
|
310 // This means we don't change state this time. |
|
311 __LOG("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - not allowed to back up this drive... trying next one..."); |
|
312 CompleteSelf( KErrNone ); |
|
313 } |
|
314 } |
|
315 else |
|
316 { |
|
317 // No more drives left, we've finished! |
|
318 __LOG("CMMCScBkupWriteDataTransferRequestBase::PrepareDataTransferL() - no more drives to process - we're finished!"); |
|
319 SetState( EFinished ); |
|
320 CompleteSelf(); |
|
321 } |
|
322 } |
|
323 } |
|
324 |
|
325 |
|
326 // --------------------------------------------------------------------------- |
|
327 // CMMCScBkupWriteDataTransferRequestBase::CurrentDrive() |
|
328 // |
|
329 // |
|
330 // --------------------------------------------------------------------------- |
|
331 TDriveNumber CMMCScBkupWriteDataTransferRequestBase::CurrentDrive() const |
|
332 { |
|
333 return iCurrentDrive; |
|
334 } |
|
335 |
|
336 |
|
337 // --------------------------------------------------------------------------- |
|
338 // CMMCScBkupWriteDataTransferRequestBase::ValidateTransferInfoL() |
|
339 // |
|
340 // |
|
341 // --------------------------------------------------------------------------- |
|
342 void CMMCScBkupWriteDataTransferRequestBase::ValidateTransferInfoL( CSBGenericTransferType* aInfo ) |
|
343 { |
|
344 if ( !aInfo ) |
|
345 { |
|
346 User::Leave( KErrCorrupt ); |
|
347 } |
|
348 |
|
349 // Check the type is as expected |
|
350 const TSBDerivedType type = aInfo->DerivedTypeL(); |
|
351 if ( type != iExpectedTransferType ) |
|
352 { |
|
353 __LOG2("CMMCScBkupWriteDataTransferRequestBase::ValidateTransferInfoL() - ERROR - types dont match! type: %d vs expected: %d", type, iExpectedTransferType ); |
|
354 User::Leave( KErrNotSupported ); |
|
355 } |
|
356 } |
|
357 |
|
358 |
|
359 // --------------------------------------------------------------------------- |
|
360 // CMMCScBkupWriteDataTransferRequestBase::RequestDataTransferL() |
|
361 // |
|
362 // |
|
363 // --------------------------------------------------------------------------- |
|
364 void CMMCScBkupWriteDataTransferRequestBase::RequestDataTransferL() |
|
365 { |
|
366 __LOG3("CMMCScBkupWriteDataTransferRequestBase::RequestDataTransferL() - requesting data from SBE for SID: 0x%08x, Drive: %c:, ElementType: %S", DataOwner().SecureId().iId, 'A' + CurrentDrive(), &MMCScBkupLogger::DataType( ElementType() ) ); |
|
367 |
|
368 CSBEClient& sbeClient = Driver().DrvSecureBackupClient(); |
|
369 sbeClient.RequestDataL( *iTransferType, iStatus ); |
|
370 SetActive(); |
|
371 SetState( EProcessData ); |
|
372 |
|
373 // Report the progress |
|
374 RMMCScBkupProgressSizer progressSizer( Driver().DrvParamsBase().DriveAndOperations() ); |
|
375 progressSizer.BackupReportFixedProgressForOpL( Driver().DrvProgressHandler(), ElementType() ); |
|
376 } |
|
377 |
|
378 |
|
379 // --------------------------------------------------------------------------- |
|
380 // CMMCScBkupWriteDataTransferRequestBase::RunError() |
|
381 // |
|
382 // |
|
383 // --------------------------------------------------------------------------- |
|
384 TInt CMMCScBkupWriteDataTransferRequestBase::RunError( TInt aError ) |
|
385 { |
|
386 #if defined(__MMCSCBKUPLOGGING_ENABLED__) |
|
387 const TSecureId sid = DataOwner().SecureId(); |
|
388 __LOGFILE3("CMMCScBkupWriteDataTransferRequestBase::RunError() - **** - aError: %d, sid: 0x%08x, drive: %c", aError, sid.iId, 'A' + CurrentDrive() ); |
|
389 #endif |
|
390 |
|
391 TInt ret = KErrNone; |
|
392 |
|
393 // Make sure we close the stream (if we had it open) |
|
394 if ( iStreamIsOpen ) |
|
395 { |
|
396 iStream.Close(); |
|
397 iStreamIsOpen = EFalse; |
|
398 } |
|
399 |
|
400 // Now notify the observer or silently try again (depends on type of error) |
|
401 if ( aError == KErrNotFound ) |
|
402 { |
|
403 __LOGFILE1("CMMCScBkupWriteDataTransferRequestBase::RunError() - **** - non fatal error (%d) so trying the next drive...", aError); |
|
404 |
|
405 // Try the next drive - if none is available, it will complete the |
|
406 // observer as if nothing went wrong. |
|
407 iAdditionalTransferRequired = EFalse; |
|
408 SetState( ETransferData ); |
|
409 CompleteSelf(); |
|
410 } |
|
411 else |
|
412 { |
|
413 __LOGFILE1("CMMCScBkupWriteDataTransferRequestBase::RunError() - **** - FATAL ERROR (%d)", aError); |
|
414 ret = CMMCScBkupTransferRequestBase::RunError( aError ); |
|
415 } |
|
416 // |
|
417 return ret; |
|
418 } |
|
419 |
|
420 |
|
421 // --------------------------------------------------------------------------- |
|
422 // CMMCScBkupWriteDataTransferRequestBase::DumpTransferDataL() |
|
423 // |
|
424 // |
|
425 // --------------------------------------------------------------------------- |
|
426 #ifdef DEBUGGING_DATA_TRANSFER |
|
427 void CMMCScBkupWriteDataTransferRequestBase::DumpTransferDataL( RFs& aFsSession, const TDesC8& aData ) const |
|
428 { |
|
429 TPtrC subDirectory( KNullDesC ); |
|
430 // |
|
431 switch( ElementType() ) |
|
432 { |
|
433 case EMMCScBkupOwnerDataTypeJavaData: |
|
434 subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataJava); |
|
435 break; |
|
436 case EMMCScBkupOwnerDataTypeSystemData: |
|
437 subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataSystem); |
|
438 break; |
|
439 case EMMCScBkupOwnerDataTypePassiveData: |
|
440 subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataPassive); |
|
441 break; |
|
442 case EMMCScBkupOwnerDataTypeActiveData: |
|
443 subDirectory.Set(KMMCScBkupDataTransferDebuggingPathDataActive); |
|
444 break; |
|
445 default: |
|
446 User::Leave( KErrNotSupported ); |
|
447 break; |
|
448 } |
|
449 // |
|
450 const TSecureId secureId = DataOwner().SecureId(); |
|
451 _LIT(KMMCScBkupFormatDes, "%S%S"); |
|
452 TFileName transferDumpFileName; |
|
453 const TDesC& path = PathInfo::MemoryCardRootPath(); |
|
454 transferDumpFileName.Format(KMMCScBkupFormatDes, &path, &KMMCScBkupDataTransferDebuggingPathRoot); |
|
455 |
|
456 transferDumpFileName.Append( subDirectory ); |
|
457 transferDumpFileName.Append( KMMCScBkupDataTransferDebuggingPathDataBackup ); |
|
458 transferDumpFileName.AppendFormat( KMMCScBkupDataTransferDebuggingFileName, secureId.iId, 'a' + CurrentDrive() ); |
|
459 // |
|
460 RFile64 file; |
|
461 TInt error = KErrNone; |
|
462 TEntry entry; |
|
463 if ( aFsSession.Entry( transferDumpFileName, entry ) == KErrNone ) |
|
464 { |
|
465 // Already exists - append data |
|
466 error = file.Open( aFsSession, transferDumpFileName, EFileWrite | EFileStream | EFileShareExclusive ); |
|
467 } |
|
468 else |
|
469 { |
|
470 entry.iSize = 0; |
|
471 error = file.Create( aFsSession, transferDumpFileName, EFileWrite | EFileStream | EFileShareExclusive ); |
|
472 } |
|
473 // |
|
474 User::LeaveIfError( error ); |
|
475 CleanupClosePushL( file ); |
|
476 error = file.Write( entry.iSize, aData ); |
|
477 CleanupStack::PopAndDestroy( &file ); |
|
478 } |
|
479 #endif |
|
480 |
|
481 |
|
482 |
|
483 |
|
484 |
|
485 |
|
486 |
|
487 |
|
488 |
|
489 |
|
490 |
|
491 |