|
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: |
|
15 * Implements interface for Logs event |
|
16 * |
|
17 */ |
|
18 |
|
19 // INCLUDE FILES |
|
20 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
21 #include <logsmspdudata.h> |
|
22 #endif |
|
23 #include "CLogsEventData.h" |
|
24 #include "LogsApiConsts.h" |
|
25 #include <AiwPoCParameters.h> //epocnooptypeid for idatatype |
|
26 |
|
27 _LIT8( KLogsDoubleDataFldNameDelimiter, "\t\t" ); |
|
28 const TInt KOneChar = 1; |
|
29 const TInt KTwoChars = 2; |
|
30 |
|
31 |
|
32 // ---------------------------------------------------------------------------- |
|
33 // CLogsEventData::NewL |
|
34 // ---------------------------------------------------------------------------- |
|
35 // |
|
36 CLogsEventData* CLogsEventData::NewL( const TDesC8 &aData, TBool aReadMessageParts ) |
|
37 { |
|
38 CLogsEventData* self = new (ELeave) CLogsEventData( aData ); |
|
39 CleanupStack::PushL( self ); |
|
40 self->ConstructL( aReadMessageParts ); |
|
41 CleanupStack::Pop( self ); |
|
42 return self; |
|
43 } |
|
44 |
|
45 |
|
46 // ---------------------------------------------------------------------------- |
|
47 // CLogsEventData::CLogsEventData |
|
48 // ---------------------------------------------------------------------------- |
|
49 // |
|
50 CLogsEventData::CLogsEventData( const TDesC8 &aData ) : |
|
51 iTempDataFieldPtr( aData ) |
|
52 { |
|
53 //NOTE It is NOT guaranteed that the TDesC8& got in as parameter is alive longer than |
|
54 //during the call to this ConstructL. Therefore the same applies to iTempDataFieldPtr we're using to point to it. |
|
55 } |
|
56 |
|
57 // ---------------------------------------------------------------------------- |
|
58 // CLogsEventData::~CLogsEventData |
|
59 // ---------------------------------------------------------------------------- |
|
60 // |
|
61 CLogsEventData::~CLogsEventData() |
|
62 { |
|
63 delete iURL8; |
|
64 delete iProfile; |
|
65 delete iId; |
|
66 delete iMyAddress8; |
|
67 delete iDataField; |
|
68 delete iContactLink; |
|
69 } |
|
70 |
|
71 // ---------------------------------------------------------------------------- |
|
72 // CLogsEventData::ConstructL |
|
73 // ---------------------------------------------------------------------------- |
|
74 // |
|
75 void CLogsEventData::ConstructL( TBool aReadMessageParts ) |
|
76 { |
|
77 //All default values must already be set in case there is no data in the event's data field. |
|
78 iALS = EFalse; |
|
79 iCNAP = EFalse; |
|
80 iVT = EFalse; |
|
81 iPoC = EFalse; |
|
82 iVoIP = EFalse; |
|
83 iEmerg = EFalse; |
|
84 iDataSent = MAKE_TINT64(0,0); |
|
85 iDataReceived = MAKE_TINT64(0,0); |
|
86 iDataType = KErrNotFound; //Provide EPoCNoOpTypeId if type is absent or non numeric |
|
87 iMsgPartsNumber = 0; //Meaningful only for sms |
|
88 iServiceId = 0; |
|
89 iContactLink = 0; |
|
90 iDataField = iTempDataFieldPtr.AllocL(); |
|
91 iURL8 = HBufC8::NewL( 0 ); //We must have a valid HBufC object even if we would not put any data to it. |
|
92 iProfile = HBufC8::NewL( 0 ); |
|
93 iId = HBufC8::NewL( 0 ); |
|
94 iMyAddress8 = HBufC8::NewL( 0 ); |
|
95 |
|
96 //1. Msg parts are written in different format in data field. |
|
97 if( aReadMessageParts ) |
|
98 { |
|
99 SetMsgPartsNumber(); |
|
100 } |
|
101 //2. else check if the sent & received data is in old format (this can be removed when creating |
|
102 // log data field entries is similar to format of other data field entries (i.e is tagged)) |
|
103 else if( CheckNonTaggedData( iTempDataFieldPtr ) ) |
|
104 { |
|
105 return; //Found and processed legacy data. |
|
106 } |
|
107 //3. Otherwise check if tagged data is available. |
|
108 else |
|
109 { |
|
110 CheckTaggedDataL(); |
|
111 } |
|
112 } |
|
113 |
|
114 // ---------------------------------------------------------------------------- |
|
115 // CLogsEventData::SetMsgPartsNumber |
|
116 // |
|
117 // Read msg parts. They are written in format of TLogSmsPduData in Data field |
|
118 // ---------------------------------------------------------------------------- |
|
119 // |
|
120 void CLogsEventData::SetMsgPartsNumber() |
|
121 { |
|
122 TPckgBuf<TLogSmsPduData> packedData; |
|
123 packedData.Copy( iTempDataFieldPtr.Ptr(), sizeof( TLogSmsPduData ) ); |
|
124 iMsgPartsNumber = packedData().iTotal; |
|
125 return; |
|
126 } |
|
127 |
|
128 // ---------------------------------------------------------------------------- |
|
129 // CLogsEventData::CheckNonTaggedData |
|
130 // ---------------------------------------------------------------------------- |
|
131 // |
|
132 TBool CLogsEventData::CheckNonTaggedData( TPtrC8 aDataPtr ) |
|
133 { |
|
134 TLex8 lex; |
|
135 TPtrC8 ptr; |
|
136 _LIT8(KDataSeparator,","); //Separator for gprs data (old legacy non-tagged format for sent and received grps data) |
|
137 |
|
138 //Here were are interested only in data that begins with number (e.g. 123445,23445) |
|
139 if( aDataPtr.Length() < 1 ) |
|
140 { |
|
141 return EFalse; //No data |
|
142 } |
|
143 else |
|
144 { //At least 1 byte of data available. Check does it begin with number. |
|
145 TInt v; |
|
146 ptr.Set( aDataPtr.Left(1) ); |
|
147 lex = ptr; |
|
148 if( lex.Val( v ) != KErrNone ) |
|
149 { |
|
150 return EFalse; //First byte does not contain number |
|
151 } |
|
152 } |
|
153 |
|
154 //Ok, data begins with number. Try to read a pair of comma separated numbers |
|
155 TInt separatorOffset = aDataPtr.Find( KDataSeparator ); |
|
156 |
|
157 if( separatorOffset + 1 > aDataPtr.Length() || separatorOffset < 0 ) |
|
158 { |
|
159 return EFalse; //No separator found. |
|
160 } |
|
161 |
|
162 //Set iDataSent |
|
163 ptr.Set( aDataPtr.Left( separatorOffset ) ); //Let's inspect on the left side of field delimiter token |
|
164 lex = ptr; |
|
165 lex.Val( iDataSent ); |
|
166 |
|
167 //Then reeceived data |
|
168 if( (separatorOffset + 1) >= aDataPtr.Length() ) |
|
169 { |
|
170 return ETrue; //Was no data after separator |
|
171 } |
|
172 |
|
173 //Set iDataReceived |
|
174 ptr.Set( aDataPtr.Mid(separatorOffset + 1, aDataPtr.Length() - separatorOffset - 1) ); |
|
175 lex = ptr; |
|
176 lex.Val( iDataReceived ); |
|
177 |
|
178 return ETrue; |
|
179 } |
|
180 |
|
181 |
|
182 // ---------------------------------------------------------------------------- |
|
183 // CLogsEventData::CheckTaggedDataL |
|
184 // ---------------------------------------------------------------------------- |
|
185 // |
|
186 void CLogsEventData::CheckTaggedDataL() |
|
187 { |
|
188 TInt dataLeft = iTempDataFieldPtr.Length(); |
|
189 |
|
190 while( dataLeft > 0 ) |
|
191 { |
|
192 TInt nextTokenStart = iTempDataFieldPtr.Find( KLogsDataFldNameDelimiter ); |
|
193 TPtrC8 delim( iTempDataFieldPtr ); |
|
194 |
|
195 // Check if there are double delimeter \t\t marks. |
|
196 // If \t in the end of the string, dont' try to check the next one! |
|
197 if ( ( (nextTokenStart + KOneChar) < iTempDataFieldPtr.Length() ) && |
|
198 ( iTempDataFieldPtr[ nextTokenStart + KOneChar ] == KLogsDataFldNameDelimiter()[ 0 ] ) ) |
|
199 { |
|
200 // Contact link needs to be decoded. Each delimiter has been duplicated to logs data. |
|
201 TInt tokenStretch = 0; |
|
202 // Delimiter pairs are skipped here and correct token place or end of data is set. |
|
203 do |
|
204 { |
|
205 delim.Set( iTempDataFieldPtr.Mid( nextTokenStart + KTwoChars ) ); |
|
206 tokenStretch = delim.Find( KLogsDataFldNameDelimiter ); |
|
207 if ( KErrNotFound == tokenStretch ) |
|
208 { |
|
209 // No more double delimiters of different data fields remaining, so take rest of data |
|
210 tokenStretch = delim.Length(); |
|
211 } |
|
212 nextTokenStart += ( tokenStretch + KTwoChars ); |
|
213 }while( iTempDataFieldPtr.Length() > nextTokenStart + KOneChar && |
|
214 iTempDataFieldPtr[ nextTokenStart + KOneChar ] == KLogsDataFldNameDelimiter()[ 0 ] ); |
|
215 } |
|
216 |
|
217 if( nextTokenStart > iTempDataFieldPtr.Length() || nextTokenStart < 0 ) |
|
218 { |
|
219 nextTokenStart = iTempDataFieldPtr.Length(); |
|
220 } |
|
221 |
|
222 TPtrC8 nameValue = iTempDataFieldPtr.Left( nextTokenStart ); //Let's inspect on the left side of field delimiter token |
|
223 TPtrC8 name; |
|
224 TPtrC8 value; |
|
225 |
|
226 TInt delimiterStart = nameValue.Find( KLogsDataFldValueDelimiter ); |
|
227 if( delimiterStart > iTempDataFieldPtr.Length() || delimiterStart < 0 ) |
|
228 { |
|
229 name.Set( nameValue ); |
|
230 //No value. Initialised to null in above (TPtrC8 value) |
|
231 } |
|
232 else |
|
233 { |
|
234 name.Set( iTempDataFieldPtr.Left( delimiterStart ) ); |
|
235 TInt length = nameValue.Length() - delimiterStart - 1; |
|
236 value.Set( iTempDataFieldPtr.Mid( delimiterStart + 1, length) );//Mid(TInt aPos, TInt aLength) |
|
237 } |
|
238 |
|
239 //Below a minor attempt to slightly speed up the string comparisons: If value already found, no need to compare same name anymore. |
|
240 //Most likely there is VT, VOIP or POC tag in the beginning of data field if any tags. |
|
241 if( !iVT && name.Compare( KLogsDataFldTag_VT ) == 0 ) |
|
242 { |
|
243 iVT = ETrue; |
|
244 } |
|
245 else if( !iCNAP && name.Compare( KLogsDataFldTag_CNAP ) == 0 ) |
|
246 { |
|
247 iCNAP = ETrue; |
|
248 } |
|
249 else if( !iEmerg && name.Compare( KLogsDataFldTag_Emergency ) == 0 ) |
|
250 { |
|
251 iEmerg = ETrue; |
|
252 } |
|
253 else if( !iPoC && name.Compare( KLogsDataFldTag_POC ) == 0 ) |
|
254 { |
|
255 iPoC = ETrue; |
|
256 } |
|
257 else if( !iVoIP && name.Compare( KLogsDataFldTag_IP ) == 0 ) |
|
258 { |
|
259 iVoIP = ETrue; |
|
260 } |
|
261 //iDataType: internal PoC data (the value relates to the TPoCOperationTypeId enumeration) |
|
262 else if( iDataType == KErrNotFound && name.Compare( KLogsDataFldTag_Type ) == 0 ) //No negative numbers in value so |
|
263 { //this should not execute more than once |
|
264 TLex8 lex; |
|
265 lex = value; |
|
266 lex.Val( iDataType ); //TLex: if parsing error, iDataType remains in it's original value |
|
267 } |
|
268 //Consider optimising these (below) in case there's tag but no value (in those cases these comparisons |
|
269 //are executed more than just once |
|
270 else if( !iURL8->Size() && name.Compare( KLogsDataFldTag_URL ) == 0 ) |
|
271 { |
|
272 delete iURL8; //Exist for sure |
|
273 iURL8 = 0; |
|
274 iURL8 = HBufC8::NewL( value.Length() ); |
|
275 TPtr8 ptr = iURL8->Des(); |
|
276 ptr.Copy( value ); //Copy the data to our own instance of HBufC* that is alive as long as *this exist |
|
277 } |
|
278 else if( !iMyAddress8->Size() && name.Compare( KLogsDataFldTag_MA ) == 0 ) |
|
279 { |
|
280 delete iMyAddress8; //Exist for sure |
|
281 iMyAddress8 = 0; |
|
282 iMyAddress8 = HBufC8::NewL( value.Length() ); |
|
283 TPtr8 ptr = iMyAddress8->Des(); |
|
284 ptr.Copy( value ); //Copy the data to our own instance of HBufC* that is alive as long as *this exist |
|
285 } |
|
286 |
|
287 // Sawfish VoIP changes >>>> |
|
288 else if( !iServiceId && name.Compare( KLogsDataFldTag_ServiceId ) == 0 ) |
|
289 { |
|
290 // get the 'iServiceId' from the value |
|
291 TLex8 lex( value ); |
|
292 TUint32 temp( iServiceId ); |
|
293 TInt err = lex.Val( iServiceId , EDecimal ); |
|
294 if( KErrNone != err ) |
|
295 { |
|
296 //if an error occurred we leave the service id unchanged |
|
297 iServiceId = temp; |
|
298 } |
|
299 } |
|
300 else if ( !iContactLink |
|
301 && name.Compare( KLogsDataFldTag_ContactLink ) == 0 ) |
|
302 { |
|
303 iContactLink = value.AllocL(); |
|
304 TPtr8 linkPtr( iContactLink->Des() ); |
|
305 |
|
306 TInt doubleDelim = linkPtr.Find( KLogsDoubleDataFldNameDelimiter ); |
|
307 // Remove duplicated delimiter(s) |
|
308 while( KErrNotFound != doubleDelim ) |
|
309 { |
|
310 linkPtr.Delete( doubleDelim, KOneChar ); |
|
311 doubleDelim = linkPtr.Find( KLogsDoubleDataFldNameDelimiter ); |
|
312 } |
|
313 } |
|
314 // <<<< Sawfish VoIP changes |
|
315 |
|
316 /***************************************************************************** |
|
317 <the tags below are not needed currently, but may be needed in the future> |
|
318 else if( !iDataSent && name.Compare( KLogsDataFldTag_DataSent ) == 0 ) |
|
319 { |
|
320 TLex8 lex; |
|
321 lex = value; |
|
322 lex.Val( iDataSent ); //TLex: if parsing error, iDataSent remains in it's original value |
|
323 } |
|
324 else if( !iDataReceived && name.Compare( KLogsDataFldTag_DataReceived ) == 0 ) |
|
325 { |
|
326 TLex8 lex; |
|
327 lex = value; |
|
328 lex.Val( iDataReceived ); //TLex: if parsing error, iDataReceived remains in it's original value |
|
329 } |
|
330 else if( !iProfile->Size() && name.Compare( KLogsDataFldTag_Profile ) == 0 ) |
|
331 { |
|
332 delete iProfile; |
|
333 iProfile = 0; |
|
334 iProfile = HBufC8::NewL( value.Length() ); |
|
335 TPtr8 ptr = iProfile->Des(); |
|
336 ptr.Copy( value ); //Copy the data to our own instance of HBufC* that is alive as long as *this exist |
|
337 } |
|
338 else if( !iId->Size() && name.Compare( KLogsDataFldTag_ID ) == 0 ) |
|
339 { |
|
340 delete iId; |
|
341 iId = 0; |
|
342 iId = HBufC8::NewL( value.Length() ); |
|
343 TPtr8 ptr = iId->Des(); |
|
344 ptr.Copy( value ); //Copy the data to our own instance of HBufC* that is alive as long as *this exist |
|
345 } |
|
346 *****************************************************************************/ |
|
347 |
|
348 |
|
349 //Process remaining data |
|
350 dataLeft = iTempDataFieldPtr.Length() - nextTokenStart -1; //Remaining data on the right side of token |
|
351 |
|
352 if( dataLeft > 0 ) |
|
353 { |
|
354 nameValue.Set( iTempDataFieldPtr.Right( dataLeft )); //Continue with remaining data on the right side of token |
|
355 iTempDataFieldPtr.Set( nameValue ); |
|
356 } |
|
357 } |
|
358 } |
|
359 |
|
360 |
|
361 |
|
362 // ---------------------------------------------------------------------------- |
|
363 // CLogsEventData::ALS |
|
364 // ---------------------------------------------------------------------------- |
|
365 // |
|
366 TBool CLogsEventData::ALS() const |
|
367 { |
|
368 return iALS; |
|
369 } |
|
370 |
|
371 // ---------------------------------------------------------------------------- |
|
372 // CLogsEventData::CNAP |
|
373 // ---------------------------------------------------------------------------- |
|
374 // |
|
375 TBool CLogsEventData::CNAP() const |
|
376 { |
|
377 return iCNAP; |
|
378 } |
|
379 |
|
380 // ---------------------------------------------------------------------------- |
|
381 // CLogsEventData::VT |
|
382 // ---------------------------------------------------------------------------- |
|
383 // |
|
384 TBool CLogsEventData::VT() const |
|
385 { |
|
386 return iVT; |
|
387 } |
|
388 |
|
389 // ---------------------------------------------------------------------------- |
|
390 // CLogsEventData::PoC |
|
391 // ---------------------------------------------------------------------------- |
|
392 // |
|
393 TBool CLogsEventData::PoC() const |
|
394 { |
|
395 return iPoC; |
|
396 } |
|
397 |
|
398 // ---------------------------------------------------------------------------- |
|
399 // CLogsEventData::VoIP |
|
400 // ---------------------------------------------------------------------------- |
|
401 // |
|
402 TBool CLogsEventData::VoIP() const |
|
403 { |
|
404 return iVoIP; |
|
405 } |
|
406 |
|
407 // ---------------------------------------------------------------------------- |
|
408 // CLogsEventData::Url |
|
409 // ---------------------------------------------------------------------------- |
|
410 // |
|
411 TDesC8& CLogsEventData::Url() const |
|
412 { |
|
413 return *iURL8; |
|
414 } |
|
415 |
|
416 // ---------------------------------------------------------------------------- |
|
417 // CLogsEventData::Profile |
|
418 // ---------------------------------------------------------------------------- |
|
419 // |
|
420 TDesC8& CLogsEventData::Profile() const |
|
421 { |
|
422 return *iProfile; |
|
423 } |
|
424 |
|
425 // ---------------------------------------------------------------------------- |
|
426 // CLogsEventData::Id |
|
427 // ---------------------------------------------------------------------------- |
|
428 // |
|
429 TDesC8& CLogsEventData::Id() const |
|
430 { |
|
431 return *iId; |
|
432 } |
|
433 |
|
434 // ---------------------------------------------------------------------------- |
|
435 // CLogsEventData::DataReceived |
|
436 // ---------------------------------------------------------------------------- |
|
437 // |
|
438 TInt64 CLogsEventData::DataReceived() const |
|
439 { |
|
440 return iDataReceived; |
|
441 } |
|
442 |
|
443 // ---------------------------------------------------------------------------- |
|
444 // CLogsEventData::DataSent |
|
445 // ---------------------------------------------------------------------------- |
|
446 // |
|
447 TInt64 CLogsEventData::DataSent() const |
|
448 { |
|
449 return iDataSent; |
|
450 } |
|
451 |
|
452 // ---------------------------------------------------------------------------- |
|
453 // CLogsEventData::Type |
|
454 // ---------------------------------------------------------------------------- |
|
455 // |
|
456 TInt CLogsEventData::Type() const |
|
457 { |
|
458 if( iDataType == KErrNotFound ) |
|
459 { |
|
460 return EPoCNoOpTypeId; //Provide EPoCNoOpTypeId if type is absent or non numeric |
|
461 } |
|
462 else |
|
463 { |
|
464 return iDataType; |
|
465 } |
|
466 } |
|
467 |
|
468 // ---------------------------------------------------------------------------- |
|
469 // CLogsEventData::MyAddress |
|
470 // ---------------------------------------------------------------------------- |
|
471 // |
|
472 TDesC8& CLogsEventData::MyAddress() |
|
473 { |
|
474 return *iMyAddress8; |
|
475 } |
|
476 |
|
477 // ---------------------------------------------------------------------------- |
|
478 // CLogsEventData::Emerg |
|
479 // ---------------------------------------------------------------------------- |
|
480 // |
|
481 TBool CLogsEventData::Emerg() const |
|
482 { |
|
483 return iEmerg; |
|
484 } |
|
485 |
|
486 // ---------------------------------------------------------------------------- |
|
487 // CLogsEventData::MsgPartsNumber |
|
488 // |
|
489 // Msg parts. This info is meaningful only for sms events |
|
490 // ---------------------------------------------------------------------------- |
|
491 // |
|
492 TInt CLogsEventData::MsgPartsNumber() const |
|
493 { |
|
494 return iMsgPartsNumber; |
|
495 } |
|
496 |
|
497 |
|
498 // Sawfish VoIP changes >>>> |
|
499 // ---------------------------------------------------------------------------- |
|
500 // CLogsEventData::ServiceId |
|
501 // |
|
502 // Returns the Service ID of the log event. |
|
503 // ---------------------------------------------------------------------------- |
|
504 // |
|
505 TUint32 CLogsEventData::ServiceId() const |
|
506 { |
|
507 return iServiceId; |
|
508 } |
|
509 |
|
510 // ---------------------------------------------------------------------------- |
|
511 // CLogsEventData::GetContactLink |
|
512 // |
|
513 // Getter for contactlink |
|
514 // ---------------------------------------------------------------------------- |
|
515 // |
|
516 TInt CLogsEventData::GetContactLink( TPtrC8& aContactLink ) |
|
517 { |
|
518 aContactLink.Set( KNullDesC8 ); |
|
519 TInt result = KErrNotFound; |
|
520 |
|
521 if ( iContactLink ) |
|
522 { |
|
523 aContactLink.Set( iContactLink->Des() ); |
|
524 result = KErrNone; |
|
525 } |
|
526 |
|
527 return result; |
|
528 } |
|
529 |
|
530 // ---------------------------------------------------------------------------- |
|
531 // CLogsEventData::DataField |
|
532 // |
|
533 // Returns the unparsed data field information. |
|
534 // ---------------------------------------------------------------------------- |
|
535 // |
|
536 TDesC8& CLogsEventData::DataField() const |
|
537 { |
|
538 return *iDataField; |
|
539 } |
|
540 // <<<< Sawfish VoIP changes |