|
1 // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 */ |
|
20 |
|
21 #include <obex.h> |
|
22 #include <obex/internal/obexinternalheader.h> |
|
23 #include <obex/internal/obexpacket.h> |
|
24 #include "logger.h" |
|
25 #include "OBEXUTIL.H" |
|
26 #include "obexheaderutil.h" |
|
27 |
|
28 IF_FLOGGING(_LIT8(KLogComponent, "obex");) |
|
29 |
|
30 /** |
|
31 Default constructor for ObexObjects |
|
32 @internalComponent |
|
33 */ |
|
34 CObexBaseObject::CObexBaseObject() |
|
35 { |
|
36 ResetHeaders(); |
|
37 } |
|
38 |
|
39 /** |
|
40 Destructor. |
|
41 */ |
|
42 CObexBaseObject::~CObexBaseObject() |
|
43 { |
|
44 FLOG(_L("CObexBaseObject Destructor\r\n")); |
|
45 ResetHeaders(); |
|
46 if (iObexHeader) |
|
47 { |
|
48 delete iObexHeader; |
|
49 } |
|
50 |
|
51 delete iHeaderSet; |
|
52 } |
|
53 |
|
54 /** |
|
55 Sets header mask to 1's (include all), but valid mask to 0's (none valid). |
|
56 Also reset progress indicators to avoid any un-initialised transfer attempts |
|
57 @internalComponent |
|
58 */ |
|
59 void CObexBaseObject::ResetHeaders() |
|
60 { |
|
61 iHeaderMask = 0xFFFF; |
|
62 iValidHeaders = 0x0000; |
|
63 iSendProgress = EError; |
|
64 iRecvProgress = EError; |
|
65 iRecvBytes = 0; |
|
66 |
|
67 if (iHttp) |
|
68 { |
|
69 iHttp->ResetAndDestroy(); |
|
70 delete iHttp; |
|
71 iHttp = NULL; |
|
72 } |
|
73 |
|
74 // Here iHeaderSet can be NULL. This method is called in |
|
75 // CObexBaseObject::CObexBaseObject() that is called before the |
|
76 // derived class ConstructL() method. iHeaderSet is constructed in |
|
77 // CreateHeaderStorageDataL() called from ConstructL(). |
|
78 // So, in the constructor it is always NULL. |
|
79 // This method is also called in CObexBaseObject::Reset() where iHeaderSet |
|
80 // will be valid. |
|
81 |
|
82 if (iHeaderSet) |
|
83 { |
|
84 iHeaderSet->SetMask(NULL); |
|
85 while (iHeaderSet->Count()) |
|
86 { |
|
87 iHeaderSet->DeleteCurrentHeader(); |
|
88 } |
|
89 } |
|
90 } |
|
91 |
|
92 /** |
|
93 @internalComponent |
|
94 */ |
|
95 void CObexBaseObject::CreateHeaderStorageDataL() |
|
96 { |
|
97 __ASSERT_DEBUG(!iHeaderSet, IrOBEXUtil::Panic(ENotNullPointer)); |
|
98 iHeaderSet = CObexHeaderSet::NewL(); |
|
99 |
|
100 if (iObexHeader == NULL) |
|
101 { |
|
102 iObexHeader = CObexHeader::NewL(); |
|
103 } |
|
104 } |
|
105 |
|
106 /** |
|
107 Set the connection id. |
|
108 This method will check the headerset for a connectionId header. If one if located, |
|
109 then this will be modified for the new HV value. If not, a new connectionId header |
|
110 will be added. |
|
111 |
|
112 @param aFourByte The connectionID to be set |
|
113 @internalComponent |
|
114 */ |
|
115 void CObexBaseObject::SetConnectionIdL(TUint32 aFourByte) |
|
116 { |
|
117 FLOG(_L(">>CObexBaseObject::SetConnectionIdL")); |
|
118 |
|
119 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
120 |
|
121 //reset the mask so all headers are searched |
|
122 //NB. SetMask sets the iterator at the start of the headerset |
|
123 iHeaderSet->SetMask(NULL); |
|
124 |
|
125 if (iHeaderSet->Find(TObexInternalHeader::EConnectionID, *iObexHeader) == KErrNone) |
|
126 { |
|
127 iHeaderSet->DeleteCurrentHeader(); |
|
128 } |
|
129 |
|
130 CObexHeader* header = CObexHeader::NewL(); |
|
131 CleanupStack::PushL(header); |
|
132 header->SetFourByte(TObexInternalHeader::EConnectionID, aFourByte); |
|
133 |
|
134 //Transfer ownership of pointer to CObexHeaderSet |
|
135 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
136 CleanupStack::Pop(header); |
|
137 |
|
138 iValidHeaders |= KObexHdrConnectionID; |
|
139 iHeaderMask |= KObexHdrConnectionID; |
|
140 |
|
141 FLOG(_L("<<CObexBaseObject::SetConnectionIdL")); |
|
142 } |
|
143 |
|
144 /** |
|
145 Returns the connection ID. |
|
146 |
|
147 @return Returns KConnIDInvalid if no connectionID is set. |
|
148 @internalComponent |
|
149 */ |
|
150 TUint32 CObexBaseObject::ConnectionID() |
|
151 { |
|
152 if (iValidHeaders & KObexHdrConnectionID) |
|
153 { |
|
154 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
155 |
|
156 //reset the mask so all headers are searched |
|
157 //NB. SetMask sets the iterator at the start of the headerset |
|
158 iHeaderSet->SetMask(NULL); |
|
159 |
|
160 if (iHeaderSet->Find(TObexInternalHeader::EConnectionID, *iObexHeader) == KErrNone) |
|
161 { |
|
162 return (iObexHeader->AsFourByte()); |
|
163 } |
|
164 else |
|
165 { |
|
166 return KConnIDInvalid; |
|
167 } |
|
168 } |
|
169 else |
|
170 { |
|
171 return KConnIDInvalid; |
|
172 } |
|
173 } |
|
174 |
|
175 /** |
|
176 Sets the Name attribute of the object. |
|
177 |
|
178 The Name is used to identify the object to the remote machine (or to identify |
|
179 a received object). Note that in general, this is quite distinct from the |
|
180 CObexFileObject::DataFile() attribute, which specifies where the body of the |
|
181 object is stored. |
|
182 |
|
183 @param aDesc Name attribute |
|
184 |
|
185 @publishedAll |
|
186 @released |
|
187 */ |
|
188 EXPORT_C void CObexBaseObject::SetNameL (const TDesC& aDesc) |
|
189 { |
|
190 LOG_LINE |
|
191 LOG_FUNC |
|
192 |
|
193 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
194 |
|
195 //reset the mask so all headers are searched |
|
196 //NB. SetMask sets the iterator at the start of the headerset |
|
197 iHeaderSet->SetMask(NULL); |
|
198 |
|
199 if (iHeaderSet->Find(TObexInternalHeader::EName, *iObexHeader) == KErrNone) |
|
200 { |
|
201 iHeaderSet->DeleteCurrentHeader(); |
|
202 } |
|
203 |
|
204 CObexHeader* header = CObexHeader::NewL(); |
|
205 CleanupStack::PushL(header); |
|
206 header->SetUnicodeL(TObexInternalHeader::EName, aDesc); |
|
207 //Transfer ownership of pointer to CObexHeaderSet |
|
208 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
209 CleanupStack::Pop(header); |
|
210 |
|
211 iValidHeaders |= KObexHdrName; |
|
212 } |
|
213 |
|
214 /** |
|
215 Sets the Type attribute of the object. |
|
216 |
|
217 This should be in the form of a valid IANA media type (see http://www.iana.org/assignments/media-types/index.html). |
|
218 |
|
219 @param aDesc Type attribute |
|
220 |
|
221 @publishedAll |
|
222 @released |
|
223 */ |
|
224 EXPORT_C void CObexBaseObject::SetTypeL (const TDesC8& aDesc) |
|
225 { |
|
226 LOG_LINE |
|
227 LOG_FUNC |
|
228 |
|
229 TInt len = aDesc.Length(); |
|
230 // make sure length does not include any null terms |
|
231 while(len && aDesc[len - 1] == 0) |
|
232 { |
|
233 --len; |
|
234 }; |
|
235 TPtrC8 src = aDesc.Left(len); |
|
236 |
|
237 //leave room for exactly one null term |
|
238 HBufC8* buf = HBufC8::NewL(src.Length() + 1); |
|
239 CleanupStack::PushL(buf); |
|
240 TPtr8 type(buf->Des()); |
|
241 type.Copy(src); |
|
242 type.Append(0); |
|
243 |
|
244 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
245 |
|
246 //reset the mask so all headers are searched |
|
247 //NB. SetMask sets the iterator at the start of the headerset |
|
248 iHeaderSet->SetMask(NULL); |
|
249 |
|
250 if (iHeaderSet->Find(TObexInternalHeader::EType, *iObexHeader) == KErrNone) |
|
251 { |
|
252 iHeaderSet->DeleteCurrentHeader(); |
|
253 } |
|
254 |
|
255 CObexHeader* header = CObexHeader::NewL(); |
|
256 CleanupStack::PushL(header); |
|
257 header->SetByteSeqL(TObexInternalHeader::EType, type); |
|
258 |
|
259 //Transfer ownership of pointer to CObexHeaderSet |
|
260 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
261 CleanupStack::Pop(header); |
|
262 |
|
263 CleanupStack::PopAndDestroy(buf); |
|
264 |
|
265 iValidHeaders |= KObexHdrType; |
|
266 |
|
267 } |
|
268 |
|
269 /** |
|
270 Sets the Length attribute of the object, in bytes. |
|
271 |
|
272 Note that this does not necessarily have to match the exact size of the body |
|
273 data, but is used to give an indication of the size to the receiving end. |
|
274 |
|
275 @param aLength Length attribute of the object |
|
276 |
|
277 @publishedAll |
|
278 @released |
|
279 */ |
|
280 EXPORT_C void CObexBaseObject::SetLengthL (const TUint32 aLength) |
|
281 { |
|
282 LOG_LINE |
|
283 LOG_FUNC |
|
284 |
|
285 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
286 |
|
287 //reset the mask so all headers are searched |
|
288 //NB. SetMask sets the iterator at the start of the headerset |
|
289 iHeaderSet->SetMask(NULL); |
|
290 |
|
291 if (iHeaderSet->Find(TObexInternalHeader::ELength, *iObexHeader) == KErrNone) |
|
292 { |
|
293 iHeaderSet->DeleteCurrentHeader(); |
|
294 } |
|
295 |
|
296 CObexHeader* header = CObexHeader::NewL(); |
|
297 CleanupStack::PushL(header); |
|
298 header->SetFourByte(TObexInternalHeader::ELength, aLength); |
|
299 //Transfer ownership of pointer to CObexHeaderSet |
|
300 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
301 CleanupStack::Pop(header); |
|
302 |
|
303 iValidHeaders |= KObexHdrLength; |
|
304 } |
|
305 |
|
306 /** |
|
307 Sets the Time attribute of the object (stored in UTC). |
|
308 |
|
309 @param aLocalTime Time attribute in local time |
|
310 |
|
311 @publishedAll |
|
312 @released |
|
313 */ |
|
314 EXPORT_C void CObexBaseObject::SetTimeL (const TTime aLocalTime) |
|
315 { |
|
316 LOG_LINE |
|
317 LOG_FUNC |
|
318 |
|
319 // Convert local time to UTC |
|
320 TTime utcTime(aLocalTime); |
|
321 utcTime -= User::UTCOffset(); |
|
322 SetUtcTimeL(utcTime); |
|
323 } |
|
324 |
|
325 /** |
|
326 Sets the Time attribute of the object (stored in UTC). |
|
327 |
|
328 @param aUtcTime Time attribute in local time |
|
329 */ |
|
330 void CObexBaseObject::SetUtcTimeL (const TTime aUtcTime) |
|
331 { |
|
332 LOG_LINE |
|
333 LOG_FUNC |
|
334 |
|
335 TBuf<16> timebuf; |
|
336 aUtcTime.FormatL(timebuf, _L("%F%Y%M%DT%H%T%SZ")); |
|
337 TBuf8<16> narrowBuf; |
|
338 narrowBuf.Copy(timebuf); |
|
339 SetTimeHeaderL(narrowBuf); |
|
340 |
|
341 iValidHeaders |= KObexHdrTime; |
|
342 } |
|
343 |
|
344 /** |
|
345 Add a descriptor as the one and only Time header in an object. |
|
346 |
|
347 @param aTimeDes A narrow descriptor which will be stored in the object. |
|
348 */ |
|
349 void CObexBaseObject::SetTimeHeaderL(const TDesC8& aTimeDes) |
|
350 { |
|
351 LOG_LINE |
|
352 LOG_FUNC |
|
353 |
|
354 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
355 |
|
356 //reset the mask so all headers are searched |
|
357 //NB. SetMask sets the iterator at the start of the headerset |
|
358 iHeaderSet->SetMask(NULL); |
|
359 |
|
360 if (iHeaderSet->Find(TObexInternalHeader::ETime, *iObexHeader) == KErrNone) |
|
361 { |
|
362 iHeaderSet->DeleteCurrentHeader(); |
|
363 } |
|
364 |
|
365 CObexHeader* header = CObexHeader::NewL(); |
|
366 CleanupStack::PushL(header); |
|
367 header->SetByteSeqL(TObexInternalHeader::ETime, aTimeDes); |
|
368 |
|
369 //Transfer ownership of pointer to CObexHeaderSet |
|
370 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
371 CleanupStack::Pop(header); |
|
372 } |
|
373 |
|
374 /** |
|
375 Sets the Description attribute of the object. |
|
376 |
|
377 This is currently the easiest way to send proprietary information along with |
|
378 an object. |
|
379 |
|
380 @param aDesc Description attribute |
|
381 |
|
382 @publishedAll |
|
383 @released |
|
384 */ |
|
385 EXPORT_C void CObexBaseObject::SetDescriptionL (const TDesC& aDesc) |
|
386 { |
|
387 LOG_LINE |
|
388 LOG_FUNC |
|
389 |
|
390 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
391 |
|
392 //reset the mask so all headers are searched |
|
393 //NB. SetMask sets the iterator at the start of the headerset |
|
394 iHeaderSet->SetMask(NULL); |
|
395 |
|
396 if (iHeaderSet->Find(TObexInternalHeader::EDescription, *iObexHeader) == KErrNone) |
|
397 { |
|
398 iHeaderSet->DeleteCurrentHeader(); |
|
399 } |
|
400 |
|
401 CObexHeader* header = CObexHeader::NewL(); |
|
402 CleanupStack::PushL(header); |
|
403 header->SetUnicodeL(TObexInternalHeader::EDescription, aDesc); |
|
404 //Transfer ownership of pointer to CObexHeaderSet |
|
405 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
406 CleanupStack::Pop(header); |
|
407 |
|
408 iValidHeaders |= KObexHdrDescription; |
|
409 } |
|
410 |
|
411 /** |
|
412 Sets the Application Parameters attribute of the object. |
|
413 |
|
414 This is expected to be of the format Tag-Length-Value, but this is not enforced. |
|
415 |
|
416 @param aDesc Application Parameters attribute |
|
417 |
|
418 @publishedAll |
|
419 @released |
|
420 */ |
|
421 EXPORT_C void CObexBaseObject::SetAppParamL (const TDesC8& aDesc) |
|
422 { |
|
423 LOG_LINE |
|
424 LOG_FUNC |
|
425 |
|
426 FLOG(_L("CObexBaseObject::SetAppParamL")); |
|
427 |
|
428 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
429 |
|
430 //reset the mask so all headers are searched |
|
431 //NB. SetMask sets the iterator at the start of the headerset |
|
432 iHeaderSet->SetMask(NULL); |
|
433 |
|
434 if (iHeaderSet->Find(TObexInternalHeader::EAppParam, *iObexHeader) == KErrNone) |
|
435 { |
|
436 iHeaderSet->DeleteCurrentHeader(); |
|
437 } |
|
438 CObexHeader* header = CObexHeader::NewL(); |
|
439 CleanupStack::PushL(header); |
|
440 header->SetByteSeqL(TObexInternalHeader::EAppParam, aDesc); |
|
441 //Transfer ownership of pointer to CObexHeaderSet |
|
442 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
443 CleanupStack::Pop(header); |
|
444 |
|
445 iValidHeaders |= KObexHdrAppParam; |
|
446 } |
|
447 |
|
448 /** |
|
449 Sets the Target attribute of the object. |
|
450 |
|
451 Generally, this will only have any useful meaning if the session Who attribute |
|
452 of the remote machine is recognised, and particularly, when connected to a |
|
453 strict peer (see CObex::IsStrictPeer()). |
|
454 |
|
455 @param aDesc Target attribute |
|
456 |
|
457 @publishedAll |
|
458 @released |
|
459 */ |
|
460 EXPORT_C void CObexBaseObject::SetTargetL (const TDesC8& aDesc) |
|
461 { |
|
462 LOG_LINE |
|
463 LOG_FUNC |
|
464 |
|
465 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
466 |
|
467 //reset the mask so all headers are searched |
|
468 //NB. SetMask sets the iterator at the start of the headerset |
|
469 iHeaderSet->SetMask(NULL); |
|
470 |
|
471 if (iHeaderSet->Find(TObexInternalHeader::ETarget, *iObexHeader) == KErrNone) |
|
472 { |
|
473 iHeaderSet->DeleteCurrentHeader(); |
|
474 } |
|
475 |
|
476 CObexHeader* header = CObexHeader::NewL(); |
|
477 CleanupStack::PushL(header); |
|
478 header->SetByteSeqL(TObexInternalHeader::ETarget, aDesc); |
|
479 //Transfer ownership of pointer to CObexHeaderSet |
|
480 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
481 CleanupStack::Pop(header); |
|
482 |
|
483 iValidHeaders |= KObexHdrTarget; |
|
484 } |
|
485 |
|
486 /** |
|
487 Add an Http header. |
|
488 |
|
489 @param aDesc HTTP header to be added to the object's collection of HTTP headers |
|
490 |
|
491 @publishedAll |
|
492 @released |
|
493 */ |
|
494 EXPORT_C void CObexBaseObject::AddHttpL (const TDesC8& aDesc) |
|
495 { |
|
496 LOG_LINE |
|
497 LOG_FUNC |
|
498 |
|
499 CObexHeader* header = CObexHeader::NewL(); |
|
500 CleanupStack::PushL(header); |
|
501 header->SetByteSeqL(TObexInternalHeader::EHttp, aDesc); |
|
502 |
|
503 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
504 |
|
505 //Transfer ownership of pointer to CObexHeaderSet |
|
506 LEAVEIFERRORL(iHeaderSet->AddHeader(header)); |
|
507 CleanupStack::Pop(header); |
|
508 |
|
509 if (!iHttp) |
|
510 { |
|
511 iHttp = new(ELeave) RPointerArray<HBufC8>(2); |
|
512 } |
|
513 |
|
514 HBufC8* buf = aDesc.AllocLC(); |
|
515 LEAVEIFERRORL(iHttp->Append(buf)); |
|
516 CleanupStack::Pop(buf); |
|
517 |
|
518 iValidHeaders |= KObexHdrHttp; |
|
519 } |
|
520 |
|
521 /** |
|
522 Adds a CObexHeader into the CObexHeaderSet |
|
523 |
|
524 @param aHeader A Pointer to a CObexHeader to be added to the CObexHeaderSet |
|
525 |
|
526 @publishedAll |
|
527 @released |
|
528 */ |
|
529 EXPORT_C void CObexBaseObject::AddHeaderL(CObexHeader& aHeader) |
|
530 { |
|
531 LOG_LINE |
|
532 LOG_FUNC |
|
533 |
|
534 if (aHeader.HI() == TObexInternalHeader::EHttp) |
|
535 { |
|
536 // Add the HTTP header into the iHttp array to keep old and new |
|
537 // http header storage consistent. |
|
538 // |
|
539 if (!iHttp) |
|
540 { |
|
541 iHttp = new(ELeave) RPointerArray<HBufC8>(2); |
|
542 } |
|
543 |
|
544 HBufC8* buf = (aHeader.AsByteSeq()).AllocLC(); |
|
545 LEAVEIFERRORL(iHttp->Append(buf)); |
|
546 CleanupStack::Pop(); |
|
547 |
|
548 iValidHeaders |= KObexHdrHttp; |
|
549 } |
|
550 |
|
551 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
552 |
|
553 //Transfer ownership of pointer to CObexHeaderSet |
|
554 LEAVEIFERRORL(iHeaderSet->AddHeader(&aHeader)); |
|
555 |
|
556 switch (aHeader.HI()) |
|
557 { |
|
558 case (TObexInternalHeader::EName) : |
|
559 { |
|
560 iValidHeaders |= KObexHdrName; |
|
561 break; |
|
562 } |
|
563 case (TObexInternalHeader::EType) : |
|
564 { |
|
565 iValidHeaders |= KObexHdrType; |
|
566 break; |
|
567 } |
|
568 case (TObexInternalHeader::ETime) : |
|
569 { |
|
570 iValidHeaders |= KObexHdrTime; |
|
571 break; |
|
572 } |
|
573 case (TObexInternalHeader::EConnectionID) : |
|
574 { |
|
575 iValidHeaders |= KObexHdrConnectionID; |
|
576 break; |
|
577 } |
|
578 case (TObexInternalHeader::ELength) : |
|
579 { |
|
580 iValidHeaders |= KObexHdrLength; |
|
581 break; |
|
582 } |
|
583 case (TObexInternalHeader::EDescription) : |
|
584 { |
|
585 iValidHeaders |= KObexHdrDescription; |
|
586 break; |
|
587 } |
|
588 case (TObexInternalHeader::ECount) : |
|
589 { |
|
590 iValidHeaders |= KObexHdrCount; |
|
591 break; |
|
592 } |
|
593 case (TObexInternalHeader::EAppParam) : |
|
594 { |
|
595 iValidHeaders |= KObexHdrAppParam; |
|
596 break; |
|
597 } |
|
598 case (TObexInternalHeader::ETarget) : |
|
599 { |
|
600 iValidHeaders |= KObexHdrTarget; |
|
601 break; |
|
602 } |
|
603 case (TObexInternalHeader::ECreatorID) : |
|
604 { |
|
605 iValidHeaders |= KObexHdrCreatorID; |
|
606 break; |
|
607 } |
|
608 case (TObexInternalHeader::EWanUUID) : |
|
609 { |
|
610 iValidHeaders |= KObexHdrWanUUID; |
|
611 break; |
|
612 } |
|
613 case (TObexInternalHeader::EObjectClass) : |
|
614 { |
|
615 iValidHeaders |= KObexHdrObjectClass; |
|
616 break; |
|
617 } |
|
618 case (TObexInternalHeader::EEndOfBody) : |
|
619 { |
|
620 __ASSERT_ALWAYS(DataSize() == 0, IrOBEXUtil::Panic(EAddingInvalidEoBHeader)); |
|
621 iValidHeaders |= KObexHdrEndOfBody; |
|
622 break; |
|
623 } |
|
624 default : |
|
625 { |
|
626 if ((aHeader.HI() & 0x30) != 0) |
|
627 { |
|
628 iValidHeaders |= KObexHdrUserDefined; |
|
629 } |
|
630 break; |
|
631 } |
|
632 } |
|
633 } |
|
634 |
|
635 /** |
|
636 Resets the object, to make it represent nothing. |
|
637 |
|
638 Call this before setting a CObexObject to represent a new object. |
|
639 |
|
640 @publishedAll |
|
641 @released |
|
642 */ |
|
643 EXPORT_C void CObexBaseObject::Reset() |
|
644 { |
|
645 LOG_LINE |
|
646 LOG_FUNC |
|
647 |
|
648 ResetHeaders(); |
|
649 ResetData(); |
|
650 } |
|
651 |
|
652 /** |
|
653 Makes a first level guess at setting the mime type from the |
|
654 file extension. |
|
655 |
|
656 This API is deprecated and may be removed at any time. For any production |
|
657 applications, the versit and the Application architecture (see |
|
658 RApaLsSession::RecognizeData) provide far more flexibilty and robustness. |
|
659 |
|
660 @deprecated 6.1 |
|
661 @internalComponent |
|
662 */ |
|
663 void CObexBaseObject::GuessTypeFromExtL(const TDesC& aExt) |
|
664 { |
|
665 _LIT(KVcfType, ".vcf"); |
|
666 _LIT(KVcsType, ".vcs"); |
|
667 _LIT(KTxtType, ".txt"); |
|
668 _LIT8(KVcard, "text/x-vCard"); |
|
669 _LIT8(KVcalendar, "text/x-vCalendar"); |
|
670 _LIT8(KTextPlain, "text/plain"); |
|
671 |
|
672 iValidHeaders &= ~KObexHdrType; // Default, if no others match |
|
673 if(!aExt.CompareC(KVcfType)) |
|
674 { |
|
675 SetTypeL(KVcard); |
|
676 return; |
|
677 } |
|
678 if(!aExt.CompareC(KVcsType)) |
|
679 { |
|
680 SetTypeL(KVcalendar); |
|
681 return; |
|
682 } |
|
683 if(!aExt.CompareC(KTxtType)) |
|
684 { |
|
685 SetTypeL(KTextPlain); |
|
686 return; |
|
687 } |
|
688 } |
|
689 |
|
690 /** |
|
691 Gets the object's Name attribute. |
|
692 |
|
693 @return Object's Name attribute or KNullDesC if it has not been set |
|
694 |
|
695 @publishedAll |
|
696 @released |
|
697 */ |
|
698 EXPORT_C const TDesC& CObexBaseObject::Name() |
|
699 { |
|
700 LOG_LINE |
|
701 LOG_FUNC |
|
702 |
|
703 if (iValidHeaders & KObexHdrName) |
|
704 { |
|
705 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
706 |
|
707 //reset the mask so all headers are searched |
|
708 //NB. SetMask sets the iterator at the start of the headerset |
|
709 iHeaderSet->SetMask(NULL); |
|
710 |
|
711 // search for a Name header in the headerset |
|
712 if (iHeaderSet->Find(TObexInternalHeader::EName, *iObexHeader) == KErrNone) |
|
713 { |
|
714 //header is found so return the HV as Unicode |
|
715 return (iObexHeader->AsUnicode()); |
|
716 } |
|
717 else |
|
718 { |
|
719 return (KNullDesC); |
|
720 } |
|
721 } |
|
722 else |
|
723 { |
|
724 return (KNullDesC); |
|
725 } |
|
726 } |
|
727 |
|
728 /** |
|
729 Gets the object's Type attribute. |
|
730 |
|
731 @return Object's Type attribute or KNullDesC8 if it has not been set |
|
732 |
|
733 @publishedAll |
|
734 @released |
|
735 */ |
|
736 EXPORT_C const TDesC8& CObexBaseObject::Type() |
|
737 { |
|
738 LOG_LINE |
|
739 LOG_FUNC |
|
740 |
|
741 if (iValidHeaders & KObexHdrType) |
|
742 { |
|
743 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
744 |
|
745 //reset the mask so all headers are searched |
|
746 //NB. SetMask sets the iterator at the start of the headerset |
|
747 iHeaderSet->SetMask(NULL); |
|
748 |
|
749 // search for a Type header in the headerset |
|
750 if (iHeaderSet->Find(TObexInternalHeader::EType, *iObexHeader) == KErrNone) |
|
751 { |
|
752 //header is found so return the HV as ByteSequence |
|
753 return (iObexHeader->AsByteSeq()); |
|
754 } |
|
755 else |
|
756 { |
|
757 return (KNullDesC8); |
|
758 } |
|
759 } |
|
760 else |
|
761 { |
|
762 return (KNullDesC8); |
|
763 } |
|
764 } |
|
765 |
|
766 /** |
|
767 Gets the object's Length attribute. |
|
768 |
|
769 Note this might not match the size of the file (if any) to transfer. |
|
770 |
|
771 @return Object's Length attribute or 0 if it has not been set |
|
772 |
|
773 @publishedAll |
|
774 @released |
|
775 */ |
|
776 EXPORT_C TUint32 CObexBaseObject::Length() |
|
777 { |
|
778 LOG_LINE |
|
779 LOG_FUNC |
|
780 |
|
781 if (iValidHeaders & KObexHdrLength) |
|
782 { |
|
783 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
784 |
|
785 //reset the mask so all headers are searched |
|
786 //NB. SetMask sets the iterator at the start of the headerset |
|
787 iHeaderSet->SetMask(NULL); |
|
788 |
|
789 // search for a Length header in the headerset |
|
790 if (iHeaderSet->Find(TObexInternalHeader::ELength, *iObexHeader) == KErrNone) |
|
791 { |
|
792 //header is found so return the HV as FourByte |
|
793 return (iObexHeader->AsFourByte()); |
|
794 } |
|
795 else |
|
796 { |
|
797 return (0); |
|
798 } |
|
799 } |
|
800 else |
|
801 { |
|
802 return (0); |
|
803 } |
|
804 } |
|
805 |
|
806 /** |
|
807 Firstly updates the iHttp list, ensuring that the entries are |
|
808 the same as those HTTP headers within the header set. |
|
809 (The iHttp list could have contained old headers that were removed from |
|
810 the headerset using the DeleteMasked operation) |
|
811 Returns a pointer to the Http header array or null if no headers defined. |
|
812 @return A pointer to the Http header array or null if no headers defined |
|
813 |
|
814 @publishedAll |
|
815 @released |
|
816 **/ |
|
817 EXPORT_C const RPointerArray<HBufC8>* CObexBaseObject::Http() const |
|
818 { |
|
819 LOG_LINE |
|
820 LOG_FUNC |
|
821 |
|
822 // if there are headers in the iHttp list |
|
823 if (iHttp && (iHttp->Count())) |
|
824 { |
|
825 |
|
826 TInt httpCount = 0; |
|
827 |
|
828 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
829 |
|
830 //reset the mask so all headers are searched |
|
831 //NB. SetMask sets the iterator at the start of the headerset |
|
832 iHeaderSet->SetMask(NULL); |
|
833 |
|
834 TInt err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader); |
|
835 while (err == KErrNone) |
|
836 { |
|
837 httpCount++; |
|
838 err = iHeaderSet->Next(); |
|
839 if (!err) |
|
840 { |
|
841 err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader); |
|
842 } |
|
843 } |
|
844 |
|
845 // check if number of HTTP in iHttp equals number in header set |
|
846 // NB. if equal then they must be the same headers due to the way that the |
|
847 // addition of HTTP headers has been implemented (ie. both AddHttpL and |
|
848 // AddHeader for Http, will update the iHTTP list, as well as HeaderSet) |
|
849 // |
|
850 if (httpCount != (iHttp->Count())) |
|
851 { |
|
852 // reset the header iterator to the start of the headerset |
|
853 iHeaderSet->First(); |
|
854 |
|
855 TInt arrayIndex = 0; |
|
856 |
|
857 // search for an Http header in the headerset |
|
858 err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader); |
|
859 |
|
860 while (err == KErrNone) |
|
861 { |
|
862 //delete items from the iHttp list until an HTTP header with the same HV value |
|
863 //as the HTTP header in the headerset has been located. |
|
864 while ((iObexHeader->AsByteSeq()) != (((*iHttp)[arrayIndex])->Des())) |
|
865 { |
|
866 delete (*iHttp)[arrayIndex]; |
|
867 (*iHttp).Remove(arrayIndex); |
|
868 } |
|
869 |
|
870 arrayIndex++; |
|
871 |
|
872 // search for an Http header in the headerset |
|
873 iHeaderSet->Next(); |
|
874 err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader); |
|
875 } |
|
876 |
|
877 // if the number of HTTP headers in the headerset is different to the iHTTP count |
|
878 // then there must be some remaining headers at the end of the list, so remove |
|
879 // them |
|
880 while (httpCount < (iHttp->Count())) |
|
881 { |
|
882 delete (*iHttp)[arrayIndex]; |
|
883 (*iHttp).Remove(arrayIndex); |
|
884 } |
|
885 } |
|
886 |
|
887 // if there are no elements in the iHttp list, delete the list and return NULL |
|
888 if (iHttp->Count() == 0) |
|
889 { |
|
890 if (iHttp) |
|
891 { |
|
892 iHttp->ResetAndDestroy(); |
|
893 delete iHttp; |
|
894 iHttp = NULL; |
|
895 } |
|
896 |
|
897 return NULL; |
|
898 } |
|
899 else |
|
900 { |
|
901 //return the iHttp pointer |
|
902 return iHttp; |
|
903 } |
|
904 } |
|
905 else //iHttp && iHttp->Count |
|
906 { |
|
907 return NULL; |
|
908 } |
|
909 } |
|
910 |
|
911 /** |
|
912 Take time string specified in ISO8601 format and convert to a TTime |
|
913 @param aTime Time descriptor in ISO8601 format |
|
914 @param aResult Object to place resultant local time. Set to 0 if conversion fails. |
|
915 */ |
|
916 void ParseISO8601Time(const TDesC& aTimeDes, TTime& aResult) |
|
917 { |
|
918 LOG_STATIC_FUNC_ENTRY |
|
919 FLOG(_L8("Parsing ISO 8601 format time")); |
|
920 |
|
921 TInt yr, mn, dy, hr, mi, sc; |
|
922 TLex lex(aTimeDes); |
|
923 aResult = 0; // return TTime(0) by default |
|
924 |
|
925 // Get date components |
|
926 TUint num; |
|
927 if (lex.Val(num) != KErrNone) |
|
928 { |
|
929 FLOG(_L8("Date not found")); |
|
930 return; |
|
931 } |
|
932 |
|
933 dy = num % 100; |
|
934 num /= 100; |
|
935 mn = num % 100; |
|
936 num /= 100; |
|
937 yr = num; |
|
938 |
|
939 if (lex.Get() != 'T') |
|
940 { |
|
941 FLOG(_L8("Char 'T' not found")); |
|
942 return; |
|
943 } |
|
944 |
|
945 // Get time components |
|
946 if (lex.Val(num) != KErrNone) |
|
947 { |
|
948 FLOG(_L8("Time not found")); |
|
949 return; |
|
950 } |
|
951 sc = num % 100; |
|
952 num /= 100; |
|
953 mi = num % 100; |
|
954 num /= 100; |
|
955 hr = num; |
|
956 |
|
957 // Convert components into a TTime |
|
958 TDateTime dt; |
|
959 if (dt.Set(yr,TMonth(mn-1),(dy-1),hr,mi,sc,0) != KErrNone) // day and month are zero based in TDateTime::Set |
|
960 { |
|
961 FLOG(_L8("Failed to convert time")); |
|
962 return; |
|
963 } |
|
964 aResult = dt; |
|
965 |
|
966 // If time is in UTC, convert to local time |
|
967 if (lex.Get() == 'Z') |
|
968 { |
|
969 aResult += User::UTCOffset(); // includes any daylight saving correction |
|
970 } |
|
971 } |
|
972 |
|
973 /** |
|
974 Returns the time attribute of the object in local time. |
|
975 Returns TTime (0) if no valid time has been set. |
|
976 |
|
977 @return Object's Time attribute in local time or TTime(0) if it has not been set |
|
978 |
|
979 @publishedAll |
|
980 @released |
|
981 **/ |
|
982 EXPORT_C const TTime CObexBaseObject::Time() |
|
983 { |
|
984 LOG_LINE |
|
985 LOG_FUNC |
|
986 |
|
987 TTime newTime = TTime(0); |
|
988 |
|
989 if (iValidHeaders & KObexHdrTime) |
|
990 { |
|
991 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
992 |
|
993 //reset the mask so all headers are searched |
|
994 //NB. SetMask sets the iterator at the start of the headerset |
|
995 iHeaderSet->SetMask(NULL); |
|
996 |
|
997 if (iHeaderSet->Find(TObexInternalHeader::ETime, *iObexHeader) == KErrNone) |
|
998 { |
|
999 TBuf16<16> localbuf; |
|
1000 localbuf.Copy(iObexHeader->AsByteSeq()); |
|
1001 |
|
1002 ParseISO8601Time(localbuf, newTime); |
|
1003 } |
|
1004 } |
|
1005 return newTime; |
|
1006 } |
|
1007 |
|
1008 /** |
|
1009 Gets the object's Description attribute. |
|
1010 |
|
1011 @return Object's Name attribute or KNullDesC if it has not been set |
|
1012 |
|
1013 @publishedAll |
|
1014 @released |
|
1015 */ |
|
1016 EXPORT_C const TDesC& CObexBaseObject::Description() |
|
1017 { |
|
1018 LOG_LINE |
|
1019 LOG_FUNC |
|
1020 |
|
1021 if (iValidHeaders & KObexHdrDescription) |
|
1022 { |
|
1023 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
1024 |
|
1025 //reset the mask so all headers are searched |
|
1026 //NB. SetMask sets the iterator at the start of the headerset |
|
1027 iHeaderSet->SetMask(NULL); |
|
1028 |
|
1029 // search for a Description header in the headerset |
|
1030 if (iHeaderSet->Find(TObexInternalHeader::EDescription, *iObexHeader) == KErrNone) |
|
1031 { |
|
1032 //header is found so return the HV as Unicode |
|
1033 return (iObexHeader->AsUnicode()); |
|
1034 } |
|
1035 else |
|
1036 { |
|
1037 return (KNullDesC); |
|
1038 } |
|
1039 } |
|
1040 else |
|
1041 { |
|
1042 return (KNullDesC); |
|
1043 } |
|
1044 } |
|
1045 |
|
1046 /** |
|
1047 Gets the object's Application Parameters attribute |
|
1048 |
|
1049 This function does not parse the Application Parameters attribute into the |
|
1050 expected Tag-Length-Value format. |
|
1051 |
|
1052 @return Object's Application Parameters attribute, or KNullDesC8 if none has been set |
|
1053 |
|
1054 @publishedAll |
|
1055 @released |
|
1056 */ |
|
1057 EXPORT_C const TDesC8& CObexBaseObject::AppParam() const |
|
1058 { |
|
1059 LOG_LINE |
|
1060 LOG_FUNC |
|
1061 |
|
1062 if (iValidHeaders & KObexHdrAppParam) |
|
1063 { |
|
1064 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
1065 |
|
1066 //reset the mask so all headers are searched |
|
1067 //NB. SetMask sets the iterator at the start of the headerset |
|
1068 iHeaderSet->SetMask(NULL); |
|
1069 |
|
1070 // search for a AppParam header in the headerset |
|
1071 if (iHeaderSet->Find(TObexInternalHeader::EAppParam, *iObexHeader) == KErrNone) |
|
1072 { |
|
1073 //header is found so return the HV as ByteSeq |
|
1074 return (iObexHeader->AsByteSeq()); |
|
1075 } |
|
1076 else |
|
1077 { |
|
1078 return (KNullDesC8); |
|
1079 } |
|
1080 } |
|
1081 else |
|
1082 { |
|
1083 return (KNullDesC8); |
|
1084 } |
|
1085 } |
|
1086 |
|
1087 /** |
|
1088 Gets the object's Target attribute. |
|
1089 |
|
1090 @return Object's Target attribute or KNullDesC8 if it has not been set |
|
1091 |
|
1092 @publishedAll |
|
1093 @released |
|
1094 */ |
|
1095 EXPORT_C const TDesC8& CObexBaseObject::Target() |
|
1096 { |
|
1097 LOG_LINE |
|
1098 LOG_FUNC |
|
1099 |
|
1100 if (iValidHeaders & KObexHdrTarget) |
|
1101 { |
|
1102 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
1103 |
|
1104 //reset the mask so all headers are searched |
|
1105 //NB. SetMask sets the iterator at the start of the headerset |
|
1106 iHeaderSet->SetMask(NULL); |
|
1107 |
|
1108 // search for a Target header in the headerset |
|
1109 if (iHeaderSet->Find(TObexInternalHeader::ETarget, *iObexHeader) == KErrNone) |
|
1110 { |
|
1111 //header is found so return the HV as ByteSeq |
|
1112 return (iObexHeader->AsByteSeq()); |
|
1113 } |
|
1114 else |
|
1115 { |
|
1116 return (KNullDesC8); |
|
1117 } |
|
1118 } |
|
1119 else |
|
1120 { |
|
1121 return (KNullDesC8); |
|
1122 } |
|
1123 } |
|
1124 |
|
1125 /** |
|
1126 @publishedAll |
|
1127 @released |
|
1128 @return A const reference to the HeaderSet object used by this object. |
|
1129 @see CObexHeaderSet |
|
1130 */ |
|
1131 EXPORT_C const CObexHeaderSet& CObexBaseObject::HeaderSet() const |
|
1132 { |
|
1133 LOG_LINE |
|
1134 LOG_FUNC |
|
1135 |
|
1136 return *iHeaderSet; |
|
1137 } |
|
1138 |
|
1139 /** |
|
1140 @publishedAll |
|
1141 @released |
|
1142 @return A reference to the HeaderSet object used by this object. |
|
1143 @see CObexHeaderSet |
|
1144 */ |
|
1145 EXPORT_C CObexHeaderSet& CObexBaseObject::HeaderSet() |
|
1146 { |
|
1147 LOG_LINE |
|
1148 LOG_FUNC |
|
1149 |
|
1150 return *iHeaderSet; |
|
1151 } |
|
1152 |
|
1153 /** |
|
1154 Prepare the object for sending. Each packet sent will contain aOpcode. |
|
1155 |
|
1156 @param aOpcode |
|
1157 @return KErrNone |
|
1158 @internalComponent |
|
1159 */ |
|
1160 TInt CObexBaseObject::InitSend(TObexOpcode aOpcode) |
|
1161 { |
|
1162 FLOG(_L("CObexBaseObject::InitSend")); |
|
1163 |
|
1164 iSendHeaders = 0; |
|
1165 iSendBytes = 0; |
|
1166 iSendOpcode = aOpcode; |
|
1167 iSendProgress = EContinue; |
|
1168 |
|
1169 return KErrNone; |
|
1170 } |
|
1171 |
|
1172 /** |
|
1173 Fill up the Connect command with the appropriate headers. |
|
1174 |
|
1175 @param aPacket The packet to be filled |
|
1176 @internalComponent |
|
1177 */ |
|
1178 void CObexBaseObject::PrepareConnectionHeader(CObexPacket &aPacket) |
|
1179 { |
|
1180 FLOG(_L("CObexBaseObject::PrepareConnectionHeader\r\n")); |
|
1181 TObexInternalHeader header; |
|
1182 |
|
1183 TObexHeaderMask remaininghdr = static_cast<TObexHeaderMask>(iValidHeaders & iHeaderMask); |
|
1184 if(remaininghdr) |
|
1185 {// ...there are some valid, unsent headers left to send. |
|
1186 //the Target header should be sent first |
|
1187 if(remaininghdr & KObexHdrTarget) |
|
1188 { |
|
1189 FLOG(_L("PrepareConnectionHeader - Preparing Target Header\r\n")); |
|
1190 |
|
1191 if ( Target() != KNullDesC8 ) |
|
1192 { |
|
1193 header.Set(TObexInternalHeader::ETarget, (const_cast<TUint8*>(Target().Ptr())), Target().Size()); |
|
1194 |
|
1195 if(aPacket.InsertData(header)) |
|
1196 { |
|
1197 iSendHeaders |= KObexHdrTarget; |
|
1198 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1199 |
|
1200 } |
|
1201 } |
|
1202 } |
|
1203 } |
|
1204 } |
|
1205 |
|
1206 /** |
|
1207 Fill up aPacket with whatever is left to be sent of the object. |
|
1208 Trys to get attribute headers out asap, |
|
1209 and tacks as much of the data part of the object onto the end of each |
|
1210 packet as will fit. Returned value goes to EComplete on the call *after* |
|
1211 the final packet has been written(i.e. indicates nothing left to do). |
|
1212 |
|
1213 @param aPacket The packet to be filled |
|
1214 @return Progress in writing out the object |
|
1215 @internalComponent |
|
1216 */ |
|
1217 CObexBaseObject::TProgress CObexBaseObject::PrepareNextSendPacket(CObexPacket &aPacket) |
|
1218 { |
|
1219 FLOG(_L("CObexBaseObject::PrepareNextSendPacket\r\n")); |
|
1220 |
|
1221 // iHeaderSet is often dereferenced in this method. So it worth to check it |
|
1222 // at the beginning |
|
1223 |
|
1224 __ASSERT_DEBUG(iHeaderSet, IrOBEXUtil::Panic(ENullPointer)); |
|
1225 |
|
1226 if(iSendProgress == ELastPacket) |
|
1227 { |
|
1228 /* |
|
1229 If the state was 'ELastPacket' as a result of the |
|
1230 last call to this method, then the last packet will |
|
1231 now have been sent! |
|
1232 */ |
|
1233 iSendProgress = EComplete; |
|
1234 } |
|
1235 |
|
1236 if(iSendProgress != EContinue) |
|
1237 { |
|
1238 FLOG(_L("PrepareNextSendPacket - immediate exit\r\n")); |
|
1239 return(iSendProgress); |
|
1240 } |
|
1241 |
|
1242 TObexInternalHeader header; |
|
1243 aPacket.Init(iSendOpcode); |
|
1244 TInt startspace = aPacket.RemainingInsertSpace(); |
|
1245 |
|
1246 TObexHeaderMask remaininghdr = static_cast<TObexHeaderMask>(~iSendHeaders & iValidHeaders & iHeaderMask); |
|
1247 TBool suppressDataHeader = EFalse; |
|
1248 TBool firstHeader = ETrue; |
|
1249 if(remaininghdr) |
|
1250 {// ...there are some valid, unsent headers left to send. |
|
1251 if(remaininghdr & KObexHdrTarget) |
|
1252 { |
|
1253 FLOG(_L("PrepareConnectionHeader - Preparing Target Header\r\n")); |
|
1254 |
|
1255 header.Set(TObexInternalHeader::ETarget, (const_cast<TUint8*> (Target().Ptr())), Target().Size()); |
|
1256 if(aPacket.InsertData(header)) |
|
1257 { |
|
1258 iSendHeaders |= KObexHdrTarget; |
|
1259 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1260 //set that a header has been added to this current packet |
|
1261 firstHeader = EFalse; |
|
1262 } |
|
1263 } |
|
1264 |
|
1265 if (remaininghdr & KObexHdrConnectionID) |
|
1266 { |
|
1267 FLOG(_L("PrepareNextSendPacket - preparing EConnectionID header\r\n")); |
|
1268 |
|
1269 TUint32 connID = ConnectionID(); |
|
1270 if ( connID != KConnIDInvalid ) |
|
1271 { |
|
1272 |
|
1273 TUint32 newConnectionID = connID; |
|
1274 header.Set(TObexInternalHeader::EConnectionID, newConnectionID); |
|
1275 |
|
1276 if(aPacket.InsertData(header)) |
|
1277 { |
|
1278 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1279 |
|
1280 iSendHeaders |= KObexHdrConnectionID; |
|
1281 //set that a header has been added to this current packet |
|
1282 firstHeader = EFalse; |
|
1283 } |
|
1284 } |
|
1285 else |
|
1286 { |
|
1287 iValidHeaders &= ~KObexHdrConnectionID; |
|
1288 } |
|
1289 } |
|
1290 |
|
1291 if(remaininghdr & KObexHdrName) |
|
1292 { |
|
1293 FLOG(_L("PrepareNextSendPacket - preparing EName header\r\n")); |
|
1294 |
|
1295 header.Set(TObexInternalHeader::EName, Name()); |
|
1296 if(aPacket.InsertData(header)) |
|
1297 { |
|
1298 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1299 |
|
1300 iSendHeaders |= KObexHdrName; |
|
1301 //set that a header has been added to this current packet |
|
1302 firstHeader = EFalse; |
|
1303 } |
|
1304 } |
|
1305 |
|
1306 if(remaininghdr & KObexHdrLength) |
|
1307 { |
|
1308 FLOG(_L("PrepareNextSendPacket - preparing ELength header\r\n")); |
|
1309 |
|
1310 header.Set(TObexInternalHeader::ELength, Length()); |
|
1311 if(aPacket.InsertData(header)) |
|
1312 { |
|
1313 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1314 |
|
1315 iSendHeaders |= KObexHdrLength; |
|
1316 //set that a header has been added to this current packet |
|
1317 firstHeader = EFalse; |
|
1318 } |
|
1319 } |
|
1320 if(remaininghdr & KObexHdrType) |
|
1321 { |
|
1322 FLOG(_L("PrepareNextSendPacket - preparing EType header\r\n")); |
|
1323 |
|
1324 header.Set(TObexInternalHeader::EType, (const_cast<TUint8*> (Type().Ptr())), Type().Size()); |
|
1325 |
|
1326 if(aPacket.InsertData(header)) |
|
1327 { |
|
1328 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1329 |
|
1330 iSendHeaders |= KObexHdrType; |
|
1331 //set that a header has been added to this current packet |
|
1332 firstHeader = EFalse; |
|
1333 } |
|
1334 } |
|
1335 |
|
1336 if(remaininghdr & KObexHdrDescription) |
|
1337 { |
|
1338 FLOG(_L("PrepareNextSendPacket - preparing EDescription header\r\n")); |
|
1339 |
|
1340 header.Set(TObexInternalHeader::EDescription, Description()); |
|
1341 if(aPacket.InsertData(header)) |
|
1342 { |
|
1343 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1344 |
|
1345 iSendHeaders |= KObexHdrDescription; |
|
1346 //set that a header has been added to this current packet |
|
1347 firstHeader = EFalse; |
|
1348 } |
|
1349 } |
|
1350 if(remaininghdr & KObexHdrCount) |
|
1351 { |
|
1352 FLOG(_L("PrepareNextSendPacket - preparing ECount header\r\n")); |
|
1353 |
|
1354 if (iValidHeaders & KObexHdrCount) |
|
1355 { |
|
1356 //reset the mask so all headers are searched |
|
1357 //NB. SetMask sets the iterator at the start of the headerset |
|
1358 iHeaderSet->SetMask(NULL); |
|
1359 |
|
1360 if (iHeaderSet->Find(TObexInternalHeader::ECount, *iObexHeader) == KErrNone) |
|
1361 { |
|
1362 |
|
1363 TUint32 newCount = iObexHeader->AsFourByte(); |
|
1364 header.Set(TObexInternalHeader::ECount, newCount); |
|
1365 |
|
1366 if(aPacket.InsertData(header)) |
|
1367 { |
|
1368 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1369 |
|
1370 iSendHeaders |= KObexHdrCount; |
|
1371 //set that a header has been added to this current packet |
|
1372 firstHeader = EFalse; |
|
1373 } |
|
1374 } |
|
1375 else |
|
1376 { |
|
1377 iValidHeaders &= ~KObexHdrCount; |
|
1378 } |
|
1379 } |
|
1380 else |
|
1381 { |
|
1382 iValidHeaders &= ~KObexHdrCount; |
|
1383 } |
|
1384 } |
|
1385 if (remaininghdr & KObexHdrAppParam) |
|
1386 { |
|
1387 FLOG(_L("PrepareNextSendPacket - preparing EAppParam header\r\n")); |
|
1388 |
|
1389 header.Set(TObexInternalHeader::EAppParam, (const_cast<TUint8*> (AppParam().Ptr())), AppParam().Size()); |
|
1390 |
|
1391 if (aPacket.InsertData(header)) |
|
1392 { |
|
1393 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1394 |
|
1395 iSendHeaders |= KObexHdrAppParam; |
|
1396 //set that a header has been added to this current packet |
|
1397 firstHeader = EFalse; |
|
1398 } |
|
1399 } |
|
1400 |
|
1401 if (remaininghdr & KObexHdrHttp) |
|
1402 { |
|
1403 //no need to check iValidHeaders as if it is false then remaininghdr would be too. |
|
1404 |
|
1405 //reset the mask so all headers are searched |
|
1406 //NB. SetMask sets the iterator at the start of the headerset |
|
1407 iHeaderSet->SetMask(NULL); |
|
1408 |
|
1409 TBool headerFound = EFalse; |
|
1410 TUint headerFoundCount = 0; |
|
1411 TUint headerHandledCount = 0; |
|
1412 |
|
1413 TInt err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader); |
|
1414 |
|
1415 while (err == KErrNone) |
|
1416 { |
|
1417 headerFoundCount++; |
|
1418 |
|
1419 if ( (!(iObexHeader->Attributes() & CObexHeader::ESent)) && |
|
1420 (!(iObexHeader->Attributes() & CObexHeader::ESuppressed)) ) |
|
1421 { |
|
1422 //Unsent and Unsuppressed Http header had been found |
|
1423 headerFound = ETrue; |
|
1424 |
|
1425 header.Set(TObexInternalHeader::EHttp, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size()); |
|
1426 |
|
1427 if(aPacket.InsertData(header)) |
|
1428 { |
|
1429 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1430 headerHandledCount++; |
|
1431 |
|
1432 //set that a header has been added to this current packet |
|
1433 firstHeader = EFalse; |
|
1434 } |
|
1435 else if (firstHeader) |
|
1436 { |
|
1437 // Had problems inserting the first HTTP header, Set it to suppressed. |
|
1438 // (this is also the first header in the packet, so we had the full |
|
1439 // packet size available) |
|
1440 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESuppressed)); |
|
1441 headerHandledCount++; |
|
1442 } |
|
1443 } |
|
1444 else |
|
1445 { |
|
1446 //Header has previously been sent/suppressed |
|
1447 headerHandledCount++; |
|
1448 } |
|
1449 |
|
1450 iHeaderSet->Next(); |
|
1451 err = iHeaderSet->Find(TObexInternalHeader::EHttp, *iObexHeader); |
|
1452 } |
|
1453 |
|
1454 if (headerFoundCount == headerHandledCount) |
|
1455 { |
|
1456 //All HTTP headers have been sent (or suppressed) |
|
1457 iSendHeaders |= KObexHdrHttp; |
|
1458 } |
|
1459 |
|
1460 // an unsent http header cannot be found in headerset so set flag to invalid |
|
1461 if (headerFound == EFalse) |
|
1462 { |
|
1463 iValidHeaders &= ~KObexHdrHttp; |
|
1464 } |
|
1465 } |
|
1466 |
|
1467 if(remaininghdr & KObexHdrCreatorID) |
|
1468 { |
|
1469 FLOG(_L("PrepareNextSendPacket - preparing ECreatorID header\r\n")); |
|
1470 |
|
1471 if (iValidHeaders & KObexHdrCreatorID) |
|
1472 { |
|
1473 //reset the mask so all headers are searched |
|
1474 //NB. SetMask sets the iterator at the start of the headerset |
|
1475 iHeaderSet->SetMask(NULL); |
|
1476 |
|
1477 if (iHeaderSet->Find(TObexInternalHeader::ECreatorID, *iObexHeader) == KErrNone) |
|
1478 { |
|
1479 header.Set(TObexInternalHeader::ECreatorID, iObexHeader->AsFourByte()); |
|
1480 if(aPacket.InsertData(header)) |
|
1481 { |
|
1482 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1483 iSendHeaders |= KObexHdrCreatorID; |
|
1484 //set that a header has been added to this current packet |
|
1485 firstHeader = EFalse; |
|
1486 } |
|
1487 } |
|
1488 else |
|
1489 { |
|
1490 iValidHeaders &= ~KObexHdrCreatorID; |
|
1491 } |
|
1492 } |
|
1493 else |
|
1494 { |
|
1495 iValidHeaders &= ~KObexHdrCreatorID; |
|
1496 } |
|
1497 } |
|
1498 |
|
1499 if(remaininghdr & KObexHdrWanUUID) |
|
1500 { |
|
1501 FLOG(_L("PrepareNextSendPacket - preparing EWanUUID header\r\n")); |
|
1502 if (iValidHeaders & KObexHdrWanUUID) |
|
1503 { |
|
1504 //reset the mask so all headers are searched |
|
1505 //NB. SetMask sets the iterator at the start of the headerset |
|
1506 iHeaderSet->SetMask(NULL); |
|
1507 |
|
1508 if (iHeaderSet->Find(TObexInternalHeader::EWanUUID, *iObexHeader) == KErrNone) |
|
1509 { |
|
1510 header.Set(TObexInternalHeader::EWanUUID, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size()); |
|
1511 if(aPacket.InsertData(header)) |
|
1512 { |
|
1513 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1514 iSendHeaders |= KObexHdrWanUUID; |
|
1515 //set that a header has been added to this current packet |
|
1516 firstHeader = EFalse; |
|
1517 } |
|
1518 } |
|
1519 else |
|
1520 { |
|
1521 iValidHeaders &= ~KObexHdrWanUUID; |
|
1522 } |
|
1523 } |
|
1524 else |
|
1525 { |
|
1526 iValidHeaders &= ~KObexHdrWanUUID; |
|
1527 } |
|
1528 } |
|
1529 |
|
1530 if(remaininghdr & KObexHdrObjectClass) |
|
1531 { |
|
1532 FLOG(_L("PrepareNextSendPacket - preparing EObjectClass header\r\n")); |
|
1533 if (iValidHeaders & KObexHdrObjectClass) |
|
1534 { |
|
1535 //reset the mask so all headers are searched |
|
1536 //NB. SetMask sets the iterator at the start of the headerset |
|
1537 iHeaderSet->SetMask(NULL); |
|
1538 |
|
1539 if (iHeaderSet->Find(TObexInternalHeader::EObjectClass, *iObexHeader) == KErrNone) |
|
1540 { |
|
1541 header.Set(TObexInternalHeader::EObjectClass, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size()); |
|
1542 if(aPacket.InsertData(header)) |
|
1543 { |
|
1544 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1545 |
|
1546 iSendHeaders |= KObexHdrObjectClass; |
|
1547 //set that a header has been added to this current packet |
|
1548 firstHeader = EFalse; |
|
1549 } |
|
1550 } |
|
1551 else |
|
1552 { |
|
1553 iValidHeaders &= ~KObexHdrObjectClass; |
|
1554 } |
|
1555 } |
|
1556 else |
|
1557 { |
|
1558 iValidHeaders &= ~KObexHdrObjectClass; |
|
1559 } |
|
1560 } |
|
1561 if (remaininghdr & KObexHdrUserDefined) |
|
1562 { |
|
1563 TBool headerFound = EFalse; |
|
1564 TUint headerFoundCount = 0; |
|
1565 TUint headerSentCount = 0; |
|
1566 TInt err = 0; |
|
1567 |
|
1568 //reset the mask so all headers are searched |
|
1569 //NB. SetMask sets the iterator at the start of the headerset |
|
1570 iHeaderSet->SetMask(NULL); |
|
1571 |
|
1572 for (TUint8 headerTypeIndex = TObexInternalHeader::EUnicode; |
|
1573 headerTypeIndex <= TObexInternalHeader::E4Byte;) |
|
1574 // NB. iterative step not included in this for loop, this is done at the end |
|
1575 //of the for loop: moves headerTypeIndex to the next type |
|
1576 { |
|
1577 |
|
1578 for (TUint8 headerNameIndex = KObexUserDefinedHdrAddrMin; |
|
1579 headerNameIndex <= KObexUserDefinedHdrAddrMax; headerNameIndex++) |
|
1580 { |
|
1581 TUint8 localHI = static_cast<TUint8>(headerTypeIndex | headerNameIndex); |
|
1582 |
|
1583 iHeaderSet->First(); |
|
1584 |
|
1585 err = iHeaderSet->Find(localHI, *iObexHeader); |
|
1586 |
|
1587 if (err == KErrNone) |
|
1588 { |
|
1589 headerFoundCount++; |
|
1590 |
|
1591 if ((iObexHeader->Attributes() & CObexHeader::ESent) == 0) |
|
1592 { |
|
1593 headerFound = ETrue; |
|
1594 |
|
1595 switch (headerTypeIndex) |
|
1596 { |
|
1597 case (TObexInternalHeader::EUnicode) : |
|
1598 { |
|
1599 header.Set(localHI, iObexHeader->AsUnicode()); |
|
1600 if(aPacket.InsertData(header)) |
|
1601 { |
|
1602 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1603 |
|
1604 headerSentCount++; |
|
1605 //set that a header has been added to this current packet |
|
1606 firstHeader = EFalse; |
|
1607 } |
|
1608 |
|
1609 break; |
|
1610 } |
|
1611 case (TObexInternalHeader::EByteSeq) : |
|
1612 { |
|
1613 header.Set(localHI, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size()); |
|
1614 |
|
1615 if(aPacket.InsertData(header)) |
|
1616 { |
|
1617 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1618 |
|
1619 headerSentCount++; |
|
1620 //set that a header has been added to this current packet |
|
1621 firstHeader = EFalse; |
|
1622 } |
|
1623 break; |
|
1624 } |
|
1625 case (TObexInternalHeader::E1Byte) : |
|
1626 { |
|
1627 header.Set(localHI, iObexHeader->AsByte()); |
|
1628 if(aPacket.InsertData(header)) |
|
1629 { |
|
1630 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1631 |
|
1632 headerSentCount++; |
|
1633 //set that a header has been added to this current packet |
|
1634 firstHeader = EFalse; |
|
1635 } |
|
1636 break; |
|
1637 } |
|
1638 case (TObexInternalHeader::E4Byte) : |
|
1639 { |
|
1640 header.Set(localHI, iObexHeader->AsFourByte()); |
|
1641 if(aPacket.InsertData(header)) |
|
1642 { |
|
1643 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1644 |
|
1645 headerSentCount++; |
|
1646 //set that a header has been added to this current packet |
|
1647 firstHeader = EFalse; |
|
1648 } |
|
1649 break; |
|
1650 } |
|
1651 default : |
|
1652 { |
|
1653 break; |
|
1654 } |
|
1655 } |
|
1656 } |
|
1657 else |
|
1658 { |
|
1659 //header has been previously sent. |
|
1660 headerSentCount++; |
|
1661 } |
|
1662 }// header not found in headerset |
|
1663 |
|
1664 } //for loop: user defined header 'name' addresses |
|
1665 |
|
1666 // set the header type to the next |
|
1667 // |
|
1668 switch (headerTypeIndex) |
|
1669 { |
|
1670 case (TObexInternalHeader::EUnicode) : |
|
1671 { |
|
1672 headerTypeIndex = TObexInternalHeader::EByteSeq; |
|
1673 break; |
|
1674 } |
|
1675 case (TObexInternalHeader::EByteSeq) : |
|
1676 { |
|
1677 headerTypeIndex = TObexInternalHeader::E1Byte; |
|
1678 break; |
|
1679 } |
|
1680 case (TObexInternalHeader::E1Byte) : |
|
1681 { |
|
1682 headerTypeIndex = TObexInternalHeader::E4Byte; |
|
1683 break; |
|
1684 } |
|
1685 case (TObexInternalHeader::E4Byte) : |
|
1686 { |
|
1687 headerTypeIndex++; // incrementing this past E4Byte will cause for loop to exit |
|
1688 break; |
|
1689 } |
|
1690 default : {break;} |
|
1691 } |
|
1692 }//for loop: user defined header 'type' addresses |
|
1693 |
|
1694 if (headerFoundCount == headerSentCount) |
|
1695 { |
|
1696 //All User defined headers have been sent |
|
1697 iSendHeaders |= KObexHdrUserDefined; |
|
1698 } |
|
1699 |
|
1700 // an unsent user defined header cannot be found in headerset so set flag to invalid |
|
1701 if (headerFound == EFalse) |
|
1702 { |
|
1703 iValidHeaders &= ~KObexHdrUserDefined; |
|
1704 } |
|
1705 } |
|
1706 |
|
1707 if(remaininghdr & KObexHdrTime) |
|
1708 {// Must be last, due to Windows 2000 parse bug (see defect v3 EDNJKIN-4N4G7K) |
|
1709 if (iValidHeaders & KObexHdrTime) |
|
1710 { |
|
1711 FLOG(_L("PrepareNextSendPacket - preparing ETime header\r\n")); |
|
1712 //reset the mask so all headers are searched |
|
1713 //NB. SetMask sets the iterator at the start of the headerset |
|
1714 iHeaderSet->SetMask(NULL); |
|
1715 |
|
1716 if (iHeaderSet->Find(TObexInternalHeader::ETime, *iObexHeader) == KErrNone) |
|
1717 { |
|
1718 header.Set(TObexInternalHeader::ETime, (const_cast<TUint8*> ((iObexHeader->AsByteSeq()).Ptr())), (iObexHeader->AsByteSeq()).Size()); |
|
1719 if(aPacket.InsertData(header)) |
|
1720 { |
|
1721 //set that a header has been added to this current packet |
|
1722 iSendHeaders |= KObexHdrTime; |
|
1723 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1724 |
|
1725 suppressDataHeader = ETrue; // Win2000 Bug work-aroung |
|
1726 firstHeader = EFalse; |
|
1727 } |
|
1728 } |
|
1729 else |
|
1730 { |
|
1731 iValidHeaders &= ~KObexHdrTime; |
|
1732 } |
|
1733 } |
|
1734 else |
|
1735 { |
|
1736 iValidHeaders &= ~KObexHdrTime; |
|
1737 } |
|
1738 } |
|
1739 |
|
1740 remaininghdr = STATIC_CAST(TObexHeaderMask, ~iSendHeaders & iValidHeaders & iHeaderMask); |
|
1741 |
|
1742 // Only add EoB if there is no other remaining headers |
|
1743 if (remaininghdr == KObexHdrEndOfBody) |
|
1744 { |
|
1745 //EoB can only be added in Empty objects. |
|
1746 __ASSERT_ALWAYS(DataSize() == 0, IrOBEXUtil::Panic(EAddingInvalidEoBHeader)); |
|
1747 header.SetHI(TObexInternalHeader::EEndOfBody); |
|
1748 |
|
1749 if(aPacket.InsertData(header)) |
|
1750 { |
|
1751 iObexHeader->SetAttributes(static_cast<TUint16>(iObexHeader->Attributes() | CObexHeader::ESent)); |
|
1752 |
|
1753 iSendHeaders |= KObexHdrEndOfBody; |
|
1754 //set that a header has been added to this current packet |
|
1755 firstHeader = EFalse; |
|
1756 } |
|
1757 else if(aPacket.RemainingInsertSpace() != startspace) //something has been added |
|
1758 { |
|
1759 //There is no enough space for EOB this round, try again next time |
|
1760 return EContinue; |
|
1761 } |
|
1762 //else if nothing has been added, EError will be returned |
|
1763 remaininghdr = STATIC_CAST(TObexHeaderMask, ~iSendHeaders & iValidHeaders & iHeaderMask); |
|
1764 } |
|
1765 } |
|
1766 |
|
1767 TInt dataspace = aPacket.RemainingInsertSpace() - KObexHeaderHILongSize; |
|
1768 TInt remainingdata = DataSize() - iSendBytes; |
|
1769 if(dataspace > 0 && remainingdata > 0 && !suppressDataHeader) |
|
1770 {// ...there's some room for data and we haven't sent it all, and we're allowed to add some |
|
1771 FLOG(_L("PrepareNextSendPacket - preparing some additional data\r\n")); |
|
1772 TPtr8 bufptr(NULL, 0); |
|
1773 if(remainingdata <= dataspace) |
|
1774 { |
|
1775 header.SetDeferred(TObexInternalHeader::EEndOfBody, &bufptr, remainingdata, remainingdata); |
|
1776 } |
|
1777 else |
|
1778 { |
|
1779 header.SetDeferred(TObexInternalHeader::EBody, &bufptr, 1, remainingdata - 1); |
|
1780 } |
|
1781 if(!aPacket.InsertData(header)) |
|
1782 { |
|
1783 return(iSendProgress = EError); |
|
1784 } |
|
1785 else |
|
1786 {// Data header inserted, now load it up with data... |
|
1787 GetData(iSendBytes, bufptr); |
|
1788 if(bufptr.Length() < bufptr.MaxLength()) |
|
1789 return(iSendProgress = EError); |
|
1790 iSendBytes += bufptr.Length(); |
|
1791 remainingdata -= bufptr.Length(); |
|
1792 } |
|
1793 } |
|
1794 |
|
1795 if(!(remaininghdr || remainingdata > 0)) |
|
1796 {// Check whether all(valid) headers and data will have been sent |
|
1797 iSendProgress = ELastPacket; |
|
1798 |
|
1799 FLOG(_L("PrepareNextSendPacket - All headers packaged setting Final Bit\r\n")); |
|
1800 aPacket.SetFinal(); |
|
1801 } |
|
1802 else if(aPacket.RemainingInsertSpace() == startspace) |
|
1803 { |
|
1804 // There are pending header or data but we inserted nothing! |
|
1805 // Some header isn't fitting into the packets provided. |
|
1806 FLOG(_L("PrepareNextSendPacket - nothing was actually inserted\r\n")); |
|
1807 iSendProgress = EError; |
|
1808 } |
|
1809 |
|
1810 return(iSendProgress); |
|
1811 } |
|
1812 |
|
1813 /** |
|
1814 Prepare the object for receiving into. |
|
1815 @internalComponent |
|
1816 */ |
|
1817 TInt CObexBaseObject::InitReceive() |
|
1818 { |
|
1819 FLOG(_L("CObexBaseObject::InitReceive\r\n")); |
|
1820 |
|
1821 // Always clear the object out before allowing it to receive anything |
|
1822 Reset(); |
|
1823 iRecvBytes = 0; |
|
1824 iRecvProgress = EContinue; |
|
1825 return(KErrNone); |
|
1826 } |
|
1827 |
|
1828 /** |
|
1829 Parse the passed packet, consuming headers into this object as appropriate. |
|
1830 The returned progress can not be relied upon to indicate completion, because |
|
1831 that is actually signalled at a diferent level, depending on the source of |
|
1832 the packet(final bit or server complete response). Returning EComplete |
|
1833 simply indicates that all of the object body has been received. |
|
1834 |
|
1835 @param aPacket The packet to extract the headers from |
|
1836 |
|
1837 @return The progress of header extraction |
|
1838 @internalComponent |
|
1839 */ |
|
1840 CObexBaseObject::TProgress CObexBaseObject::ParseNextReceivePacket(CObexPacket &aPacket) |
|
1841 { |
|
1842 iLastError = ERespInternalError; |
|
1843 FLOG(_L("CObexBaseObject::ParseNextReceivePacket\r\n")); |
|
1844 |
|
1845 if(iRecvProgress != EContinue && iRecvProgress != EComplete) |
|
1846 { |
|
1847 FLOG(_L("CObexBaseObject::ParseNextReceivePacket Error!!! Exiting\r\n")); |
|
1848 return(iSendProgress); |
|
1849 } |
|
1850 TObexInternalHeader header; |
|
1851 |
|
1852 while(aPacket.ExtractData(header)) |
|
1853 { |
|
1854 switch(header.HI()) |
|
1855 { |
|
1856 case TObexInternalHeader::EConnectionID: |
|
1857 { |
|
1858 if ( iHeaderMask & KObexHdrConnectionID ) |
|
1859 { |
|
1860 FLOG(_L("ParseNextReceivePacket extracting CONNECTIONID\r\n")); |
|
1861 |
|
1862 iValidHeaders &= ~KObexHdrConnectionID; |
|
1863 |
|
1864 TRAPD(err, SetConnectionIdL(header.HVInt())); |
|
1865 |
|
1866 if (err) |
|
1867 { |
|
1868 return EError; |
|
1869 } |
|
1870 } |
|
1871 } |
|
1872 break; |
|
1873 case TObexInternalHeader::EAppParam: |
|
1874 { |
|
1875 if ( iHeaderMask & KObexHdrAppParam ) |
|
1876 { |
|
1877 FLOG(_L("ParseNextReceivePacket extracting APPPARAM\r\n")); |
|
1878 iValidHeaders &= ~KObexHdrAppParam; |
|
1879 |
|
1880 |
|
1881 TPtrC8 src(header.HVByteSeq(), header.HVSize()); |
|
1882 TRAPD(err, SetAppParamL(src)); |
|
1883 if (err) |
|
1884 { |
|
1885 return EError; |
|
1886 } |
|
1887 |
|
1888 iValidHeaders |= KObexHdrAppParam; |
|
1889 } |
|
1890 } |
|
1891 break; |
|
1892 case TObexInternalHeader::EHttp: |
|
1893 { |
|
1894 FLOG(_L("ParseNextReceivePacket extracting Http\r\n")); |
|
1895 |
|
1896 TPtrC8 src(header.HVByteSeq(), header.HVSize()); |
|
1897 |
|
1898 TRAPD(err, AddHttpL(src)); |
|
1899 |
|
1900 if (err) |
|
1901 { |
|
1902 return EError; |
|
1903 } |
|
1904 } |
|
1905 break; |
|
1906 case TObexInternalHeader::EName: |
|
1907 { |
|
1908 if(iHeaderMask & KObexHdrName) |
|
1909 { |
|
1910 FLOG(_L("ParseNextReceivePacket Extracting NAME")); |
|
1911 iValidHeaders &= ~KObexHdrName; |
|
1912 |
|
1913 HBufC* newHeader = HBufC::New(header.HVSize()); |
|
1914 if (!newHeader) |
|
1915 { |
|
1916 return EError; |
|
1917 } |
|
1918 //else |
|
1919 TPtr ptr(newHeader->Des()); |
|
1920 |
|
1921 TInt err = KErrNone; |
|
1922 |
|
1923 if(header.GetHVText(ptr) == KErrNone) |
|
1924 { |
|
1925 TRAP(err, SetNameL(*newHeader)); |
|
1926 } |
|
1927 delete newHeader; |
|
1928 newHeader = NULL; |
|
1929 |
|
1930 if (err) |
|
1931 { |
|
1932 return EError; |
|
1933 } |
|
1934 } |
|
1935 |
|
1936 } |
|
1937 break; |
|
1938 case TObexInternalHeader::EType: |
|
1939 { |
|
1940 if(iHeaderMask & KObexHdrType) |
|
1941 { |
|
1942 FLOG(_L("ParseNextReceivePacket extracting TYPE\r\n")); |
|
1943 iValidHeaders &= ~KObexHdrType; |
|
1944 |
|
1945 TPtrC8 src(header.HVByteSeq(), header.HVSize()); |
|
1946 // use SetTypeL(), to ensure null terms are handled correctly |
|
1947 TRAPD(err, SetTypeL(src)); |
|
1948 if (err) |
|
1949 { |
|
1950 return EError; |
|
1951 } |
|
1952 |
|
1953 FLOG(_L("ParseNextReceivePacket extracting TYPE\r\n")); |
|
1954 } |
|
1955 } |
|
1956 break; |
|
1957 case TObexInternalHeader::ELength: |
|
1958 { |
|
1959 if(iHeaderMask & KObexHdrLength) |
|
1960 { |
|
1961 FLOG(_L("ParseNextReceivePacket extracting LENGTH\r\n")); |
|
1962 TRAPD(err, SetLengthL(header.HVInt())); |
|
1963 |
|
1964 if (err) |
|
1965 { |
|
1966 return EError; |
|
1967 } |
|
1968 |
|
1969 iValidHeaders |= KObexHdrLength; |
|
1970 } |
|
1971 } |
|
1972 break; |
|
1973 case TObexInternalHeader::ETime:// Time is ISO 8601 format byte sequence. |
|
1974 { |
|
1975 if(iHeaderMask & KObexHdrTime) |
|
1976 { |
|
1977 FLOG(_L("ParseNextReceivePacket extracting TIME in ISO 8601 format\r\n")); |
|
1978 TInt err = KErrGeneral; |
|
1979 TTime time; |
|
1980 |
|
1981 // Use Win2k's incorrect TIME format header to calculate the size required. |
|
1982 // 2k inserts incorrect padding and uses Unicode format. Allow a little extra |
|
1983 // just in case. (Currently this should be 48 bytes) |
|
1984 static const TInt KMaxTIMESize = sizeof("yyyy.mm.ddThh:mm:ssZ") * 2 + 6; |
|
1985 TBuf<KMaxTIMESize> timebuf; |
|
1986 |
|
1987 if(header.GetHVText(timebuf) == KErrNone && timebuf.LocateF('t') >= 0) |
|
1988 { |
|
1989 // Win2k sends an invalid TIME header, inserting unicode into a ByteSeq |
|
1990 // header, and inserting . and : characters between fields. So copy char |
|
1991 // by char, ignoring invalid characters. |
|
1992 TBuf8<16> narrowTime; |
|
1993 #ifdef _DEBUG |
|
1994 TBool changed = EFalse; |
|
1995 #endif |
|
1996 for (TInt copyByte = 0; copyByte <= timebuf.Length()-1; copyByte++) |
|
1997 { |
|
1998 TChar chr(timebuf[copyByte]); |
|
1999 if (chr && (chr != 0x2e /* . */) && (chr != 0x3a /* : */)) |
|
2000 { |
|
2001 if (narrowTime.Length() < narrowTime.MaxLength()) |
|
2002 { |
|
2003 narrowTime.Append(chr); |
|
2004 } |
|
2005 } |
|
2006 #ifdef _DEBUG |
|
2007 else |
|
2008 { |
|
2009 changed = ETrue; |
|
2010 } |
|
2011 #endif |
|
2012 } |
|
2013 |
|
2014 // As we've mangled the header, output a log entry just in case... |
|
2015 FTRACE(if (changed) FLOG(_L(" - Windows non-compliant time header detected and converted"))); |
|
2016 |
|
2017 TRAP(err, SetTimeHeaderL(narrowTime)); |
|
2018 } |
|
2019 |
|
2020 if(err) |
|
2021 { |
|
2022 // Adding TIME header to object failed (out of memory?). |
|
2023 FLOG(_L("ParseNextReceivePacket extracting TIME in ISO 8601 format failed")); |
|
2024 |
|
2025 // if adding TIME header to object failed, the header is ignored and the packet accepted |
|
2026 iValidHeaders &= ~KObexHdrTime; |
|
2027 } |
|
2028 else |
|
2029 { |
|
2030 // Adding TIME header succeeded, make a note. |
|
2031 iValidHeaders |= KObexHdrTime; |
|
2032 } |
|
2033 } |
|
2034 } |
|
2035 break; |
|
2036 case KFourByteTimeHeaderAddress : // Time is no. of secs since 1/1/1970 |
|
2037 if (iHeaderMask & KObexHdrTime) |
|
2038 { |
|
2039 FLOG(_L("ParseNextReceivePacket extracting TIME in secs since 1/1/1970")); |
|
2040 TTimeIntervalSeconds secs = header.HVInt(); |
|
2041 TRAPD(err, SetTimeL(TTime(TDateTime(1970, EJanuary, 0, 0, 0, 0, 0)) + secs)); |
|
2042 |
|
2043 if(err) |
|
2044 { |
|
2045 return EError; |
|
2046 } |
|
2047 |
|
2048 iValidHeaders |= KObexHdrTime; |
|
2049 } |
|
2050 break; |
|
2051 case TObexInternalHeader::EDescription: |
|
2052 { |
|
2053 if(iHeaderMask & KObexHdrDescription) |
|
2054 { |
|
2055 FLOG(_L("ParseNextReceivePacket extracting DESCRIPTION\r\n")); |
|
2056 iValidHeaders &= ~KObexHdrDescription; |
|
2057 |
|
2058 HBufC* newHeader = HBufC::New(header.HVSize()); |
|
2059 if (!newHeader) |
|
2060 { |
|
2061 return EError; |
|
2062 } |
|
2063 //else |
|
2064 TPtr ptr(newHeader->Des()); |
|
2065 |
|
2066 TInt err = KErrNone; |
|
2067 |
|
2068 if(header.GetHVText(ptr) == KErrNone) |
|
2069 { |
|
2070 TRAP(err, SetDescriptionL(*newHeader)); |
|
2071 } |
|
2072 delete newHeader; |
|
2073 newHeader = NULL; |
|
2074 |
|
2075 if (err) |
|
2076 { |
|
2077 return EError; |
|
2078 } |
|
2079 } |
|
2080 } |
|
2081 break; |
|
2082 case TObexInternalHeader::ECount: |
|
2083 { |
|
2084 if(iHeaderMask & KObexHdrCount) |
|
2085 { |
|
2086 FLOG(_L("ParseNextReceivePacket extracting Count\r\n")); |
|
2087 |
|
2088 CObexHeader* newHeader = NULL; |
|
2089 TRAPD( err, newHeader = CObexHeader::NewL()); |
|
2090 if (err) |
|
2091 { |
|
2092 return EError; |
|
2093 } |
|
2094 newHeader->SetFourByte(TObexInternalHeader::ECount, header.HVInt()); |
|
2095 |
|
2096 //Transfer ownership of pointer to CObexHeaderSet |
|
2097 err = iHeaderSet->AddHeader(newHeader); |
|
2098 if (err) |
|
2099 { |
|
2100 delete newHeader; |
|
2101 newHeader = NULL; |
|
2102 return EError; |
|
2103 } |
|
2104 iValidHeaders |= KObexHdrCount; |
|
2105 } |
|
2106 } |
|
2107 break; |
|
2108 case TObexInternalHeader::ETarget: |
|
2109 { |
|
2110 if(iHeaderMask & KObexHdrTarget) |
|
2111 { |
|
2112 FLOG(_L("ParseNextReceivePacket extracting TARGET\r\n")); |
|
2113 iValidHeaders &= ~KObexHdrTarget; |
|
2114 |
|
2115 TPtrC8 src(header.HVByteSeq(), header.HVSize()); |
|
2116 TRAPD(err, SetTargetL(src)); |
|
2117 if (err) |
|
2118 { |
|
2119 return EError; |
|
2120 } |
|
2121 } |
|
2122 } |
|
2123 break; |
|
2124 case TObexInternalHeader::ECreatorID: |
|
2125 { |
|
2126 if(iHeaderMask & KObexHdrCreatorID) |
|
2127 { |
|
2128 FLOG(_L("ParseNextReceivePacket Extracting CreatorID header")); |
|
2129 |
|
2130 CObexHeader* fourByteHeader = NULL; |
|
2131 TRAPD( err, fourByteHeader = CObexHeader::NewL()); |
|
2132 if (err) |
|
2133 { |
|
2134 return EError; |
|
2135 } |
|
2136 fourByteHeader->SetFourByte(TObexInternalHeader::ECreatorID, header.HVInt()); |
|
2137 //Transfer ownership of pointer to CObexHeaderSet |
|
2138 err = iHeaderSet->AddHeader(fourByteHeader); |
|
2139 if (err) |
|
2140 { |
|
2141 delete fourByteHeader; |
|
2142 fourByteHeader = NULL; |
|
2143 return EError; |
|
2144 } |
|
2145 iValidHeaders |= KObexHdrCreatorID; |
|
2146 } |
|
2147 } |
|
2148 break; |
|
2149 case TObexInternalHeader::EWanUUID: |
|
2150 { |
|
2151 if(iHeaderMask & KObexHdrWanUUID) |
|
2152 { |
|
2153 FLOG(_L("ParseNextReceivePacket Extracting WanUUID header")); |
|
2154 TPtrC8 src(header.HVByteSeq(), header.HVSize()); |
|
2155 |
|
2156 CObexHeader* byteseqHeader = NULL; |
|
2157 |
|
2158 byteseqHeader = IrOBEXHeaderUtil::CreateAndSetByteSeqHeader(TObexInternalHeader::EWanUUID, src); |
|
2159 if (!byteseqHeader) |
|
2160 { |
|
2161 return EError; |
|
2162 } |
|
2163 |
|
2164 //Transfer ownership of pointer to CObexHeaderSet |
|
2165 TInt err = iHeaderSet->AddHeader(byteseqHeader); |
|
2166 if (err) |
|
2167 { |
|
2168 delete byteseqHeader; |
|
2169 byteseqHeader = NULL; |
|
2170 return EError; |
|
2171 } |
|
2172 |
|
2173 iValidHeaders |= KObexHdrWanUUID; |
|
2174 } |
|
2175 } |
|
2176 break; |
|
2177 case TObexInternalHeader::EObjectClass: |
|
2178 { |
|
2179 if(iHeaderMask & KObexHdrObjectClass) |
|
2180 { |
|
2181 FLOG(_L("ParseNextReceivePacket Extracting WanUUID header")); |
|
2182 TPtrC8 src(header.HVByteSeq(), header.HVSize()); |
|
2183 |
|
2184 CObexHeader* byteseqHeader = NULL; |
|
2185 |
|
2186 byteseqHeader = IrOBEXHeaderUtil::CreateAndSetByteSeqHeader(TObexInternalHeader::EObjectClass, src); |
|
2187 if (!byteseqHeader) |
|
2188 { |
|
2189 return EError; |
|
2190 } |
|
2191 |
|
2192 //Transfer ownership of pointer to CObexHeaderSet |
|
2193 TInt err = iHeaderSet->AddHeader(byteseqHeader); |
|
2194 if (err) |
|
2195 { |
|
2196 delete byteseqHeader; |
|
2197 byteseqHeader = NULL; |
|
2198 return EError; |
|
2199 } |
|
2200 |
|
2201 iValidHeaders |= KObexHdrObjectClass; |
|
2202 } |
|
2203 } |
|
2204 break; |
|
2205 case TObexInternalHeader::EBody: |
|
2206 iValidHeaders |= KObexHdrBody; |
|
2207 //Fall-through |
|
2208 case TObexInternalHeader::EEndOfBody: |
|
2209 { |
|
2210 FLOG(_L("ParseNextReceivePacket extracting BODY\r\n")); |
|
2211 TPtr8 ptr(header.HVByteSeq(), header.HVSize(), header.HVSize()); |
|
2212 |
|
2213 if(header.HI() == TObexInternalHeader::EEndOfBody) |
|
2214 {// Body finished, there _could_ still be more headers, however... |
|
2215 iValidHeaders |= KObexHdrEndOfBody; |
|
2216 FLOG(_L("ParseNextReceivePacket extracting ENDOFBODY\r\n")); |
|
2217 iRecvProgress = EComplete; |
|
2218 } |
|
2219 |
|
2220 NewData(iRecvBytes, ptr); |
|
2221 if(ptr.Length() < header.HVSize()) |
|
2222 { |
|
2223 return(iRecvProgress = EError); |
|
2224 } |
|
2225 iRecvBytes += ptr.Length(); |
|
2226 } |
|
2227 break; |
|
2228 case TObexInternalHeader::EAuthChallenge: |
|
2229 { |
|
2230 iLastError = ERespUnauthorized; |
|
2231 return EError; |
|
2232 } |
|
2233 default: |
|
2234 { |
|
2235 // Non Standard header received so check for user defined header |
|
2236 // NB. All user defined headers are in range 0x30..0x3F |
|
2237 |
|
2238 if ((iHeaderMask & KObexHdrUserDefined) && |
|
2239 ((header.HI() & 0x30) != 0)) |
|
2240 { |
|
2241 FLOG(_L("ParseNextReceivePacket Extracting User Defined Unicode header")); |
|
2242 if( IrOBEXHeaderUtil::ParseHeader(header, *iHeaderSet) == KErrNone) |
|
2243 { |
|
2244 iValidHeaders |= KObexHdrUserDefined; |
|
2245 } |
|
2246 else |
|
2247 { |
|
2248 return EError; |
|
2249 } |
|
2250 } |
|
2251 |
|
2252 } // End of default |
|
2253 |
|
2254 } // End of header type switch |
|
2255 } // End of while |
|
2256 |
|
2257 return(iRecvProgress); |
|
2258 } |
|
2259 |
|
2260 /** |
|
2261 Returns the Obex Error response code from the last call to CObexBaseObject::ParseNextReceivePacket |
|
2262 |
|
2263 @return The Obex Response code |
|
2264 @internalComponent |
|
2265 */ |
|
2266 |
|
2267 TObexResponse CObexBaseObject::GetLastError() const |
|
2268 { |
|
2269 return iLastError; |
|
2270 } |
|
2271 |
|
2272 /** |
|
2273 Sets the header mask. aHeaderMask is built up by bit-wise ‘or’ing any of |
|
2274 the KObexHdr... constants. |
|
2275 For example, if it is set to KObexHdrName | KObexHdrLength, only |
|
2276 these two headers will be specified in transfer operations with the remote |
|
2277 machine, even if there are other valid attributes which could be used. In |
|
2278 effect, this mask is bit-wise ‘and’ed with the "valid headers" mask when |
|
2279 determining which headers are valid for the purposes of transfers. |
|
2280 |
|
2281 @param aHeaderMask: the header mask to be set |
|
2282 |
|
2283 @publishedAll |
|
2284 @released |
|
2285 **/ |
|
2286 EXPORT_C void CObexBaseObject::SetHeaderMask(const TObexHeaderMask aHeaderMask) |
|
2287 { |
|
2288 LOG_LINE |
|
2289 LOG_FUNC |
|
2290 |
|
2291 iHeaderMask=aHeaderMask; |
|
2292 } |
|
2293 |
|
2294 /** |
|
2295 Returns the number of bytes of the body of the object transferred so far |
|
2296 while sending this object. |
|
2297 |
|
2298 @return The number of bytes sent |
|
2299 |
|
2300 @publishedAll |
|
2301 @released |
|
2302 **/ |
|
2303 EXPORT_C TInt CObexBaseObject::BytesSent() |
|
2304 { |
|
2305 LOG_LINE |
|
2306 LOG_FUNC |
|
2307 |
|
2308 return(iSendBytes); |
|
2309 } |
|
2310 |
|
2311 /** |
|
2312 Returns the number of bytes of the body of the object transferred while |
|
2313 receiving an object. |
|
2314 |
|
2315 @return The number of bytes received |
|
2316 @publishedAll |
|
2317 @released |
|
2318 */ |
|
2319 EXPORT_C TInt CObexBaseObject::BytesReceived() |
|
2320 { |
|
2321 LOG_LINE |
|
2322 LOG_FUNC |
|
2323 |
|
2324 return(iRecvBytes); |
|
2325 } |
|
2326 |
|
2327 /** |
|
2328 Returns the currently set header mask. This defaults to 0xFF (i.e. allow |
|
2329 everything) when Reset () or InitFromFileL is called. This does not specify |
|
2330 which headers currently contain valid data--merely which headers will be |
|
2331 transferred if they do contain valid data. |
|
2332 |
|
2333 @return The currently set header mask |
|
2334 @publishedAll |
|
2335 @released |
|
2336 */ |
|
2337 EXPORT_C TObexHeaderMask CObexBaseObject::HeaderMask() |
|
2338 { |
|
2339 LOG_LINE |
|
2340 LOG_FUNC |
|
2341 |
|
2342 return iHeaderMask; |
|
2343 } |
|
2344 |
|
2345 /** |
|
2346 Returns the current valid header mask. This allows inspection of the current |
|
2347 set of valid headers, particularly useful for determining whether a put |
|
2348 object contained a body header (important for deleting files as part of file |
|
2349 transfer). |
|
2350 |
|
2351 @return The current valid header mask |
|
2352 @publishedAll |
|
2353 @released |
|
2354 */ |
|
2355 EXPORT_C TObexHeaderMask CObexBaseObject::ValidHeaders() |
|
2356 { |
|
2357 LOG_LINE |
|
2358 LOG_FUNC |
|
2359 |
|
2360 return iValidHeaders; |
|
2361 } |