1 /*
2 Kopete Oscar Protocol
3 icquserinfo.h - ICQ User Info Data Types
4
5 Copyright (c) 2004 Matt Rogers <mattr@kde.org>
6 Copyright (c) 2006 Roman Jarosz <kedgedev@centrum.cz>
7
8 Kopete (c) 2002-2006 by the Kopete developers <kopete-devel@kde.org>
9
10 *************************************************************************
11 * *
12 * This library is free software; you can redistribute it and/or *
13 * modify it under the terms of the GNU Lesser General Public *
14 * License as published by the Free Software Foundation; either *
15 * version 2 of the License, or (at your option) any later version. *
16 * *
17 *************************************************************************
18 */
19
20 #include "icquserinfo.h"
21 #include "buffer.h"
22
23 #include <kdebug.h>
24
ICQShortInfo()25 ICQShortInfo::ICQShortInfo()
26 {
27 uin = 0;
28 needsAuth.init( false );
29 webAware.init( false );
30 }
31
fill(Buffer * buffer)32 void ICQShortInfo::fill( Buffer* buffer )
33 {
34 if ( buffer->getByte() == 0x0A )
35 {
36 kDebug(OSCAR_RAW_DEBUG) << "Parsing ICQ short user info packet";
37 nickname = buffer->getLELNTS();
38 firstName = buffer->getLELNTS();
39 lastName = buffer->getLELNTS();
40 email = buffer->getLELNTS();
41 needsAuth = ( buffer->getByte() == 0x00 );
42 webAware = ( buffer->getByte() != 0x02 );
43 // gender = buffer->getByte();
44 }
45 else
46 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ short user info packet";
47 }
48
store(Buffer * buffer)49 void ICQShortInfo::store( Buffer* buffer )
50 {
51 if ( needsAuth.hasChanged() )
52 {
53 buffer->addLETLV8( 0x02F8, ( needsAuth.get() ) ? 0x00 : 0x01 );
54 }
55
56 if ( webAware.hasChanged() )
57 {
58 buffer->addLETLV8( 0x030C, ( webAware.get() ) ? 0x01 : 0x00 );
59 }
60 }
61
ICQGeneralUserInfo()62 ICQGeneralUserInfo::ICQGeneralUserInfo()
63 {
64 uin.init( 0 );
65 country.init( 0 );
66 timezone.init( 0 );
67 publishEmail.init( false );
68 webAware.init( false );
69 allowsDC.init( false );
70 needsAuth.init( false );
71 }
72
fill(Buffer * buffer)73 void ICQGeneralUserInfo::fill( Buffer* buffer )
74 {
75 if ( buffer->getByte() == 0x0A )
76 {
77 kDebug(OSCAR_RAW_DEBUG) << "Parsing ICQ basic user info packet";
78 nickName = buffer->getLELNTS();
79 firstName = buffer->getLELNTS();
80 lastName = buffer->getLELNTS();
81 email = buffer->getLELNTS();
82 city = buffer->getLELNTS();
83 state = buffer->getLELNTS();
84 phoneNumber = buffer->getLELNTS();
85 faxNumber = buffer->getLELNTS();
86 address = buffer->getLELNTS();
87 cellNumber = buffer->getLELNTS();
88 zip = buffer->getLELNTS();
89 country = buffer->getLEWord();
90 timezone = buffer->getLEByte(); // UTC+(tzcode * 30min)
91 needsAuth = ( buffer->getByte() == 0x00 );
92 webAware = ( buffer->getByte() == 0x01 );
93 allowsDC = ( buffer->getByte() == 0x01 ); //taken from sim
94 publishEmail = ( buffer->getByte() == 0x01 );
95 }
96 else
97 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ basic user info packet";
98 }
99
store(Buffer * buffer)100 void ICQGeneralUserInfo::store( Buffer* buffer )
101 {
102 if ( nickName.hasChanged() )
103 {
104 Buffer buf;
105 buf.addLELNTS( nickName.get() );
106 buffer->addLETLV( 0x0154, buf );
107 }
108 if ( firstName.hasChanged() )
109 {
110 Buffer buf;
111 buf.addLELNTS( firstName.get() );
112 buffer->addLETLV( 0x0140, buf );
113 }
114 if ( lastName.hasChanged() )
115 {
116 Buffer buf;
117 buf.addLELNTS( lastName.get() );
118 buffer->addLETLV( 0x014A, buf );
119 }
120 if ( email.hasChanged() || publishEmail.hasChanged() )
121 {
122 Buffer buf;
123 buf.addLELNTS( email.get() );
124 buf.addByte( ( publishEmail.get() ) ? 0x00 : 0x01 );
125 buffer->addLETLV( 0x015E, buf );
126 }
127 if ( city.hasChanged() )
128 {
129 Buffer buf;
130 buf.addLELNTS( city.get() );
131 buffer->addLETLV( 0x0190, buf );
132 }
133 if ( state.hasChanged() )
134 {
135 Buffer buf;
136 buf.addLELNTS( state.get() );
137 buffer->addLETLV( 0x019A, buf );
138 }
139 if ( phoneNumber.hasChanged() )
140 {
141 Buffer buf;
142 buf.addLELNTS( phoneNumber.get() );
143 buffer->addLETLV( 0x0276, buf );
144 }
145 if ( faxNumber.hasChanged() )
146 {
147 Buffer buf;
148 buf.addLELNTS( faxNumber.get() );
149 buffer->addLETLV( 0x0280, buf );
150 }
151 if ( address.hasChanged() )
152 {
153 Buffer buf;
154 buf.addLELNTS( address.get() );
155 buffer->addLETLV( 0x0262, buf );
156 }
157 if ( cellNumber.hasChanged() )
158 {
159 Buffer buf;
160 buf.addLELNTS( cellNumber.get() );
161 buffer->addLETLV( 0x028A, buf );
162 }
163 if ( zip.hasChanged() )
164 {
165 Buffer buf;
166 buf.addLELNTS( zip.get() );
167 buffer->addLETLV( 0x026D, buf );
168 }
169 if ( country.hasChanged() )
170 {
171 buffer->addLETLV16( 0x01A4, country.get() );
172 }
173 if ( timezone.hasChanged() )
174 {
175 buffer->addLETLV8( 0x0316, timezone.get() );
176 }
177 if ( webAware.hasChanged() )
178 {
179 buffer->addLETLV8( 0x030C, ( webAware.get() ) ? 0x01 : 0x00 );
180 }
181 if ( needsAuth.hasChanged() )
182 {
183 buffer->addLETLV8( 0x02F8, ( needsAuth.get() ) ? 0x00 : 0x01 );
184 }
185 }
186
ICQWorkUserInfo()187 ICQWorkUserInfo::ICQWorkUserInfo()
188 {
189 country.init( 0 );
190 occupation.init( 0 );
191 }
192
fill(Buffer * buffer)193 void ICQWorkUserInfo::fill( Buffer* buffer )
194 {
195 if ( buffer->getByte() == 0x0A )
196 {
197 city = buffer->getLELNTS();
198 state = buffer->getLELNTS();
199 phone = buffer->getLELNTS();
200 fax = buffer->getLELNTS();
201 address = buffer->getLELNTS();
202 zip = buffer->getLELNTS();
203 country = buffer->getLEWord();
204 company = buffer->getLELNTS();
205 department = buffer->getLELNTS();
206 position = buffer->getLELNTS();
207 occupation = buffer->getLEWord();
208 homepage = buffer->getLELNTS();
209 }
210 else
211 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ work user info packet";
212 }
213
store(Buffer * buffer)214 void ICQWorkUserInfo::store( Buffer* buffer )
215 {
216 if ( city.hasChanged() )
217 {
218 Buffer buf;
219 buf.addLELNTS( city.get() );
220 buffer->addLETLV( 0x029E, buf );
221 }
222
223 if ( state.hasChanged() )
224 {
225 Buffer buf;
226 buf.addLELNTS( state.get() );
227 buffer->addLETLV( 0x02A8, buf );
228 }
229
230 if ( phone.hasChanged() )
231 {
232 Buffer buf;
233 buf.addLELNTS( phone.get() );
234 buffer->addLETLV( 0x02C6, buf );
235 }
236
237 if ( fax.hasChanged() )
238 {
239 Buffer buf;
240 buf.addLELNTS( fax.get() );
241 buffer->addLETLV( 0x02D0, buf );
242 }
243
244 if ( address.hasChanged() )
245 {
246 Buffer buf;
247 buf.addLELNTS( address.get() );
248 buffer->addLETLV( 0x0294, buf );
249 }
250
251 if ( zip.hasChanged() )
252 {
253 Buffer buf;
254 buf.addLELNTS( zip.get() );
255 buffer->addLETLV( 0x02BD, buf );
256 }
257
258 if ( country.hasChanged() )
259 {
260 buffer->addLETLV16( 0x02B2, country.get() );
261 }
262
263 if ( company.hasChanged() )
264 {
265 Buffer buf;
266 buf.addLELNTS( company.get() );
267 buffer->addLETLV( 0x01AE, buf );
268 }
269
270 if ( department.hasChanged() )
271 {
272 Buffer buf;
273 buf.addLELNTS( department.get() );
274 buffer->addLETLV( 0x01B8, buf );
275 }
276
277 if ( position.hasChanged() )
278 {
279 Buffer buf;
280 buf.addLELNTS( position.get() );
281 buffer->addLETLV( 0x01C2, buf );
282 }
283
284 if ( occupation.hasChanged() )
285 {
286 buffer->addLETLV16( 0x01CC, occupation.get() );
287 }
288
289 if ( homepage.hasChanged() )
290 {
291 Buffer buf;
292 buf.addLELNTS( homepage.get() );
293 buffer->addLETLV( 0x02DA, buf );
294 }
295 }
296
ICQMoreUserInfo()297 ICQMoreUserInfo::ICQMoreUserInfo()
298 {
299 age.init( 0 );
300 gender.init( 0 );
301 birthdayYear.init( 0 );
302 birthdayMonth.init( 0 );
303 birthdayDay.init( 0 );
304 lang1.init( 0 );
305 lang2.init( 0 );
306 lang3.init( 0 );
307 ocountry.init( 0 );
308 marital.init( 0 );
309 sendInfo.init( false );
310 }
311
fill(Buffer * buffer)312 void ICQMoreUserInfo::fill( Buffer* buffer )
313 {
314 if ( buffer->getByte() == 0x0A )
315 {
316 age = buffer->getLEWord();
317 gender = buffer->getByte();
318 homepage = buffer->getLELNTS();
319 birthdayYear = buffer->getLEWord();
320 birthdayMonth = buffer->getByte();
321 birthdayDay = buffer->getByte();
322 lang1 = buffer->getByte();
323 lang2 = buffer->getByte();
324 lang3 = buffer->getByte();
325 buffer->getLEWord(); //emtpy field
326 ocity = buffer->getLELNTS();
327 ostate = buffer->getLELNTS();
328 ocountry = buffer->getLEWord();
329 marital = buffer->getByte();
330 sendInfo = buffer->getByte();
331 }
332 else
333 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ work user info packet";
334 }
335
store(Buffer * buffer)336 void ICQMoreUserInfo::store( Buffer* buffer )
337 {
338 if ( age.hasChanged() )
339 {
340 buffer->addLETLV16( 0x0172, age.get() );
341 }
342
343 if ( gender.hasChanged() )
344 {
345 buffer->addLETLV8( 0x017C, gender.get() );
346 }
347
348 if ( homepage.hasChanged() )
349 {
350 Buffer buf;
351 buf.addLELNTS( homepage.get() );
352 buffer->addLETLV( 0x0213, buf );
353 }
354
355 if ( birthdayYear.hasChanged() || birthdayMonth.hasChanged() || birthdayDay.hasChanged() )
356 {
357 Buffer buf;
358 buf.addLEWord( birthdayYear.get() );
359 buf.addLEWord( birthdayMonth.get() );
360 buf.addLEWord( birthdayDay.get() );
361 buffer->addLETLV( 0x023A, buf );
362 }
363
364 if ( lang1.hasChanged() || lang2.hasChanged() || lang3.hasChanged() )
365 {
366 buffer->addLETLV16( 0x0186, lang1.get() );
367 buffer->addLETLV16( 0x0186, lang2.get() );
368 buffer->addLETLV16( 0x0186, lang3.get() );
369 }
370
371 if ( ocity.hasChanged() )
372 {
373 Buffer buf;
374 buf.addLELNTS( ocity.get() );
375 buffer->addLETLV( 0x0320, buf );
376 }
377
378 if ( ostate.hasChanged() )
379 {
380 Buffer buf;
381 buf.addLELNTS( ostate.get() );
382 buffer->addLETLV( 0x032A, buf );
383 }
384
385 if ( ocountry.hasChanged() )
386 {
387 buffer->addLETLV16( 0x0334, ocountry.get() );
388 }
389
390 // if ( marital.hasChanged() )
391 // {
392 // }
393
394 if ( sendInfo.hasChanged() )
395 {
396 buffer->addLETLV8( 0x0348, sendInfo.get() );
397 }
398 }
399
ICQEmailInfo()400 ICQEmailInfo::ICQEmailInfo()
401 {
402 }
403
fill(Buffer * buffer)404 void ICQEmailInfo::fill( Buffer* buffer )
405 {
406 if ( buffer->getByte() == 0x0A )
407 {
408 QList<EmailItem> emails;
409 int numEmails = buffer->getByte();
410 for ( int i = 0; i < numEmails; i++ )
411 {
412 EmailItem item;
413 item.publish = ( buffer->getByte() == 0x00 );
414 item.email = buffer->getLELNTS();
415 emails.append( item );
416 }
417 emailList = emails;
418 }
419 else
420 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ email user info packet";
421 }
422
store(Buffer * buffer)423 void ICQEmailInfo::store( Buffer* buffer )
424 {
425 if ( emailList.hasChanged() )
426 {
427 int size = emailList.get().size();
428 for ( int i = 0; i < size; i++ )
429 {
430 EmailItem item = emailList.get().at(i);
431
432 Buffer buf;
433 buf.addLELNTS( item.email );
434 buf.addByte( ( item.publish ) ? 0x00 : 0x01 );
435 buffer->addLETLV( 0x015E, buf );
436 }
437 }
438 }
439
ICQNotesInfo()440 ICQNotesInfo::ICQNotesInfo()
441 {
442 }
443
fill(Buffer * buffer)444 void ICQNotesInfo::fill( Buffer* buffer )
445 {
446 if ( buffer->getByte() == 0x0A )
447 notes = buffer->getLELNTS();
448 else
449 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ notes user info packet";
450 }
451
store(Buffer * buffer)452 void ICQNotesInfo::store( Buffer* buffer )
453 {
454 if ( notes.hasChanged() )
455 {
456 Buffer buf;
457 buf.addLELNTS( notes.get() );
458 buffer->addLETLV( 0x0258, buf );
459 }
460 }
461
ICQInterestInfo()462 ICQInterestInfo::ICQInterestInfo()
463 {
464 for ( int i = 0; i < 4; i++ )
465 topics[i].init( 0 );
466 }
467
fill(Buffer * buffer)468 void ICQInterestInfo::fill( Buffer* buffer )
469 {
470 if ( buffer->getByte() == 0x0A )
471 {
472 int count=0; //valid interests
473 int len= buffer->getByte(); //interests we get
474 for ( int i = 0; i < len; i++ )
475 {
476 int t=buffer->getLEWord();
477 QByteArray d = buffer->getLELNTS();
478 if (count<4) { //i think this could not happen, i have never seen more
479 topics[count]=t;
480 descriptions[count]=d;
481 count++;
482 } else {
483 kDebug(OSCAR_RAW_DEBUG) << "got more than four interest infos";
484 }
485 }
486 if ( count < 4 )
487 {
488 for ( int i = count; i < 4; i++ )
489 {
490 topics[i] = 0;
491 descriptions[i] = QByteArray();
492 }
493 }
494 kDebug(OSCAR_RAW_DEBUG) << "LEN: "<< len << " COUNT: " << count;
495 }
496 else
497 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ interest user info packet";
498 }
499
store(Buffer * buffer)500 void ICQInterestInfo::store( Buffer* buffer )
501 {
502 bool hasChanged = false;
503 for ( int i = 0; i < 4; i++ )
504 {
505 if ( topics[i].hasChanged() || descriptions[i].hasChanged() )
506 {
507 hasChanged = true;
508 break;
509 }
510 }
511
512 if ( hasChanged )
513 {
514 for ( int i = 0; i < 4; i++ )
515 {
516 if ( topics[i].get() != 0 )
517 {
518 Buffer buf;
519 buf.addLEWord( topics[i].get() );
520 buf.addLELNTS( descriptions[i].get() );
521 buffer->addLETLV( 0x01EA, buf );
522 }
523 }
524 }
525 }
526
ICQOrgAffInfo()527 ICQOrgAffInfo::ICQOrgAffInfo()
528 {
529 org1Category.init( 0 );
530 org2Category.init( 0 );
531 org3Category.init( 0 );
532 pastAff1Category.init( 0 );
533 pastAff2Category.init( 0 );
534 pastAff3Category.init( 0 );
535 }
536
fill(Buffer * buffer)537 void ICQOrgAffInfo::fill( Buffer* buffer )
538 {
539 if ( buffer->getByte() == 0x0A )
540 {
541 if ( buffer->getByte() != 0x03 )
542 {
543 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ affiliation info packet";
544 return;
545 }
546
547 pastAff1Category = buffer->getLEWord();
548 pastAff1Keyword = buffer->getLELNTS();
549 pastAff2Category = buffer->getLEWord();
550 pastAff2Keyword = buffer->getLELNTS();
551 pastAff3Category = buffer->getLEWord();
552 pastAff3Keyword = buffer->getLELNTS();
553
554 if ( buffer->getByte() != 0x03 )
555 {
556 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ organization info packet";
557 return;
558 }
559
560 org1Category = buffer->getLEWord();
561 org1Keyword = buffer->getLELNTS();
562 org2Category = buffer->getLEWord();
563 org2Keyword = buffer->getLELNTS();
564 org3Category = buffer->getLEWord();
565 org3Keyword = buffer->getLELNTS();
566 }
567 else
568 kDebug(OSCAR_RAW_DEBUG) << "Couldn't parse ICQ organization & affiliation info packet";
569
570 }
571
store(Buffer * buffer)572 void ICQOrgAffInfo::store( Buffer* buffer )
573 {
574 if ( org1Category.hasChanged() || org1Keyword.hasChanged() ||
575 org2Category.hasChanged() || org2Keyword.hasChanged() ||
576 org3Category.hasChanged() || org3Keyword.hasChanged() )
577 {
578 if ( org1Category.get() != 0 )
579 {
580 Buffer buf;
581 buf.addLEWord( org1Category.get() );
582 buf.addLELNTS( org1Keyword.get() );
583 buffer->addLETLV( 0x01FE, buf );
584 }
585
586 if ( org2Category.get() != 0 )
587 {
588 Buffer buf;
589 buf.addLEWord( org2Category.get() );
590 buf.addLELNTS( org2Keyword.get() );
591 buffer->addLETLV( 0x01FE, buf );
592 }
593
594 if ( org3Category.get() != 0 )
595 {
596 Buffer buf;
597 buf.addLEWord( org3Category.get() );
598 buf.addLELNTS( org3Keyword.get() );
599 buffer->addLETLV( 0x01FE, buf );
600 }
601 }
602
603 if ( pastAff1Category.hasChanged() || pastAff1Keyword.hasChanged() ||
604 pastAff2Category.hasChanged() || pastAff2Keyword.hasChanged() ||
605 pastAff3Category.hasChanged() || pastAff3Keyword.hasChanged() )
606 {
607 if ( pastAff1Category.get() != 0 )
608 {
609 Buffer buf;
610 buf.addLEWord( pastAff1Category.get() );
611 buf.addLELNTS( pastAff1Keyword.get() );
612 buffer->addLETLV( 0x01D6, buf );
613 }
614
615 if ( pastAff2Category.get() != 0 )
616 {
617 Buffer buf;
618 buf.addLEWord( pastAff2Category.get() );
619 buf.addLELNTS( pastAff2Keyword.get() );
620 buffer->addLETLV( 0x01D6, buf );
621 }
622
623 if ( pastAff3Category.get() != 0 )
624 {
625 Buffer buf;
626 buf.addLEWord( pastAff3Category.get() );
627 buf.addLELNTS( pastAff3Keyword.get() );
628 buffer->addLETLV( 0x01D6, buf );
629 }
630 }
631 }
632
ICQSearchResult()633 ICQSearchResult::ICQSearchResult()
634 {
635 auth = false;
636 online = false;
637 gender = 'U';
638 }
639
fill(Buffer * buffer)640 void ICQSearchResult::fill( Buffer* buffer )
641 {
642 buffer->getLEWord(); // data length ( eat it )
643
644 uin = buffer->getLEDWord();
645 kDebug(OSCAR_RAW_DEBUG) << "Found UIN " << QString::number( uin );
646
647 nickName = buffer->getLELNTS();
648 firstName = buffer->getLELNTS();
649 lastName = buffer->getLELNTS();
650 email = buffer->getLELNTS();
651
652 auth = ( buffer->getByte() != 0x01 );
653 online = ( buffer->getLEWord() == 0x0001 );
654 switch ( buffer->getByte() )
655 {
656 case 0x00:
657 gender = 'M';
658 break;
659 case 0x01:
660 gender = 'F';
661 break;
662 default:
663 gender = 'U';
664 break;
665 }
666 age = buffer->getLEWord();
667 }
668
ICQWPSearchInfo()669 ICQWPSearchInfo::ICQWPSearchInfo()
670 {
671 age = 0;
672 gender = 0;
673 language = 0;
674 country = 0;
675 occupation = 0;
676 onlineOnly = false;
677 }
678
ICQFullInfo(bool assumeDirty)679 ICQFullInfo::ICQFullInfo( bool assumeDirty )
680 : uin(assumeDirty), firstName(assumeDirty), lastName(assumeDirty), nickName(assumeDirty),
681 homepage(assumeDirty), gender(assumeDirty), webAware(assumeDirty), privacyProfile(assumeDirty),
682 language1(assumeDirty), language2(assumeDirty), language3(assumeDirty),
683 statusDescription(assumeDirty), timezone(assumeDirty), notes(assumeDirty),
684 homeList(assumeDirty), originList(assumeDirty), workList(assumeDirty),
685 interestList(assumeDirty), organizationList(assumeDirty), pastAffliationList(assumeDirty),
686 phoneList(assumeDirty)
687 {
688 uin.init( 0 );
689 timezone.init( 0 );
690 }
691
fill(Buffer * buffer)692 void ICQFullInfo::fill( Buffer* buffer )
693 {
694 Buffer tlvListBuffer( buffer->getBSTR() );
695 QList<TLV> tlvList = tlvListBuffer.getTLVList();
696
697 QList<TLV>::const_iterator it;
698 for ( it = tlvList.constBegin(); it != tlvList.constEnd(); ++it )
699 {
700 switch ( (*it).type )
701 {
702 case 0x0032:
703 uin = (*it).data;
704 break;
705 case 0x0046:
706 break;
707 case 0x0050:
708 break;
709 case 0x0055:
710 break;
711 case 0x0064:
712 firstName = (*it).data;
713 break;
714 case 0x006e:
715 lastName = (*it).data;
716 break;
717 case 0x0078:
718 nickName = (*it).data;
719 break;
720 case 0x0082:
721 {
722 Buffer b( (*it).data );
723 gender = b.getByte();
724 }
725 break;
726 case 0x008c:
727 break;
728 case 0x0096:
729 homeList = parseAddressItemList( (*it).data );
730 break;
731 case 0x00A0:
732 originList = parseAddressItemList( (*it).data );
733 break;
734 case 0x00AA:
735 {
736 Buffer b( (*it).data );
737 language1 = b.getWord();
738 }
739 break;
740 case 0x00B4:
741 {
742 Buffer b( (*it).data );
743 language2 = b.getWord();
744 }
745 break;
746 case 0x00BE:
747 {
748 Buffer b( (*it).data );
749 language3 = b.getWord();
750 }
751 break;
752 case 0x00C8:
753 phoneList = parseInfoItemList( (*it).data );
754 break;
755 case 0x00FA:
756 homepage = (*it).data;
757 break;
758 case 0x0104:
759 break;
760 case 0x010e:
761 break;
762 case 0x0118:
763 workList = parseWorkItemList( (*it).data );
764 break;
765 case 0x0122:
766 interestList = parseInfoItemList( (*it).data );
767 break;
768 case 0x0123:
769 organizationList = parseInfoItemList( (*it).data );
770 break;
771 case 0x0124:
772 pastAffliationList = parseInfoItemList( (*it).data );
773 break;
774 case 0x012C:
775 break;
776 case 0x0136:
777 break;
778 case 0x0140:
779 break;
780 case 0x014A:
781 break;
782 case 0x0154:
783 break;
784 case 0x015E:
785 break;
786 case 0x0168:
787 break;
788 case 0x0172:
789 break;
790 case 0x017C:
791 timezone = Buffer( (*it).data ).getWord();
792 break;
793 case 0x0186:
794 notes = (*it).data;
795 break;
796 case 0x0190:
797 break;
798 case 0x019A:
799 {
800 Buffer b( (*it).data );
801 webAware = (b.getWord() == 0x0001);
802 }
803 break;
804 case 0x01A4:
805 break;
806 case 0x01AE:
807 break;
808 case 0x01B8:
809 break;
810 case 0x01C2:
811 break;
812 case 0x01CC:
813 break;
814 case 0x01D6:
815 break;
816 case 0x01E0:
817 break;
818 case 0x01EA:
819 break;
820 case 0x01F4:
821 break;
822 case 0x01F9:
823 {
824 Buffer b( (*it).data );
825 privacyProfile = b.getWord();
826 }
827 break;
828 case 0x01FE:
829 break;
830 case 0x0208:
831 break;
832 case 0x0212:
833 break;
834 case 0x021C:
835 break;
836 case 0x0226:
837 statusDescription = (*it).data;
838 break;
839 case 0x0230:
840 break;
841 case 0x003C:
842 break;
843 default:
844 kDebug(OSCAR_RAW_DEBUG) << "Unhandled tlv: " << hex << (*it).type << " data: " << hex << (*it).data;
845 break;
846 }
847 }
848 }
849
store(Buffer * buffer)850 void ICQFullInfo::store( Buffer* buffer )
851 {
852 buffer->startBlock( Buffer::BWord );
853
854 // if ( unknown.hasChanged() )
855 // buffer->addTLV( 0x0046, unknown.get() );
856
857 // if ( unknown.hasChanged() )
858 // buffer->addTLV( 0x0050, unknown.get() );
859
860 // if ( unknown.hasChanged() )
861 // buffer->addTLV( 0x0055, unknown.get() );
862
863 if ( firstName.hasChanged() )
864 buffer->addTLV( 0x0064, firstName.get() );
865
866 if ( lastName.hasChanged() )
867 buffer->addTLV( 0x006e, lastName.get() );
868
869 if ( nickName.hasChanged() )
870 buffer->addTLV( 0x0078, nickName.get() );
871
872 if ( gender.hasChanged() )
873 buffer->addTLV8( 0x0082, gender.get() );
874
875 // if ( unknown.hasChanged() )
876 // buffer->addTLV( 0x008c, unknown.get() );
877
878 if ( homeList.hasChanged() )
879 buffer->addTLV( 0x0096, storeAddressItemList( homeList.get() ) );
880
881 if ( originList.hasChanged() )
882 buffer->addTLV( 0x00A0, storeAddressItemList( originList.get() ) );
883
884 if ( language1.hasChanged() )
885 buffer->addTLV16( 0x00AA, language1.get() );
886
887 if ( language2.hasChanged() )
888 buffer->addTLV16( 0x00B4, language2.get() );
889
890 if ( language3.hasChanged() )
891 buffer->addTLV16( 0x00BE, language3.get() );
892
893 if ( phoneList.hasChanged() )
894 buffer->addTLV( 0x00C8, storeInfoItemList( phoneList.get() ) );
895
896 if ( homepage.hasChanged() )
897 buffer->addTLV( 0x00FA, homepage.get() );
898
899 // if ( unknown.hasChanged() )
900 // buffer->addTLV( 0x0104, unknown.get() );
901
902 // if ( unknown.hasChanged() )
903 // buffer->addTLV( 0x010e, unknown.get() );
904
905 if ( workList.hasChanged() )
906 buffer->addTLV( 0x0118, storeWorkItemList( workList.get() ) );
907
908 if ( interestList.hasChanged() )
909 buffer->addTLV( 0x0122, storeInfoItemList( interestList.get() ) );
910
911 if ( organizationList.hasChanged() )
912 buffer->addTLV( 0x0123, storeInfoItemList( organizationList.get() ) );
913
914 if ( pastAffliationList.hasChanged() )
915 buffer->addTLV( 0x0124, storeInfoItemList( pastAffliationList.get() ) );
916
917 // if ( unknown.hasChanged() )
918 // buffer->addTLV( 0x012C, unknown.get() );
919
920 // if ( unknown.hasChanged() )
921 // buffer->addTLV( 0x0136, unknown.get() );
922
923 // if ( unknown.hasChanged() )
924 // buffer->addTLV( 0x0140, unknown.get() );
925
926 // if ( unknown.hasChanged() )
927 // buffer->addTLV( 0x014A, unknown.get() );
928
929 // if ( unknown.hasChanged() )
930 // buffer->addTLV( 0x0154, unknown.get() );
931
932 // if ( unknown.hasChanged() )
933 // buffer->addTLV( 0x015E, unknown.get() );
934
935 // if ( unknown.hasChanged() )
936 // buffer->addTLV( 0x0168, unknown.get() );
937
938 // if ( unknown.hasChanged() )
939 // buffer->addTLV( 0x0172, unknown.get() );
940
941 if ( timezone.hasChanged() )
942 buffer->addTLV16( 0x017C, timezone.get() );
943
944 if ( notes.hasChanged() )
945 buffer->addTLV( 0x0186, notes.get() );
946
947 // if ( unknown.hasChanged() )
948 // buffer->addTLV( 0x0190, unknown.get() );
949
950 if ( webAware.hasChanged() )
951 buffer->addTLV16( 0x019A, webAware.get() ? 0x0001 : 0x0000 );
952
953 // if ( unknown.hasChanged() )
954 // buffer->addTLV( 0x01A4, unknown.get() );
955
956 // if ( unknown.hasChanged() )
957 // buffer->addTLV( 0x01AE, unknown.get() );
958
959 // if ( unknown.hasChanged() )
960 // buffer->addTLV( 0x01B8, unknown.get() );
961
962 // if ( unknown.hasChanged() )
963 // buffer->addTLV( 0x01C2, unknown.get() );
964
965 // if ( unknown.hasChanged() )
966 // buffer->addTLV( 0x01CC, unknown.get() );
967
968 // if ( unknown.hasChanged() )
969 // buffer->addTLV( 0x01D6, unknown.get() );
970
971 // if ( unknown.hasChanged() )
972 // buffer->addTLV( 0x01E0, unknown.get() );
973
974 // if ( unknown.hasChanged() )
975 // buffer->addTLV( 0x01EA, unknown.get() );
976
977 // if ( unknown.hasChanged() )
978 // buffer->addTLV( 0x01F4, unknown.get() );
979
980 if ( privacyProfile.hasChanged() )
981 buffer->addTLV16( 0x01F9, privacyProfile.get() );
982
983 // if ( unknown.hasChanged() )
984 // buffer->addTLV( 0x01FE, unknown.get() );
985
986 // if ( unknown.hasChanged() )
987 // buffer->addTLV( 0x0208, unknown.get() );
988
989 // if ( unknown.hasChanged() )
990 // buffer->addTLV( 0x0212, unknown.get() );
991
992 // if ( unknown.hasChanged() )
993 // buffer->addTLV( 0x021C, unknown.get() );
994
995 if ( statusDescription.hasChanged() )
996 buffer->addTLV( 0x0226, statusDescription.get() );
997
998 // if ( unknown.hasChanged() )
999 // buffer->addTLV( 0x0230, unknown.get() );
1000
1001 // if ( unknown.hasChanged() )
1002 // buffer->addTLV( 0x003C, unknown.get() );
1003
1004 buffer->endBlock();
1005 }
1006
parseAddressItemList(const QByteArray & data) const1007 ICQFullInfo::AddressItemList ICQFullInfo::parseAddressItemList( const QByteArray& data ) const
1008 {
1009 Buffer buffer( data );
1010 AddressItemList infoList;
1011
1012 int count = buffer.getWord();
1013 while ( (count--) > 0 )
1014 {
1015 QList<TLV> tlvList = Buffer( buffer.getBSTR() ).getTLVList();
1016
1017 AddressItem info;
1018 QList<TLV>::const_iterator it;
1019 for ( it = tlvList.constBegin(); it != tlvList.constEnd(); ++it )
1020 {
1021 switch ( (*it).type )
1022 {
1023 case 0x0064:
1024 info.address = (*it).data;
1025 break;
1026 case 0x006E:
1027 info.city = (*it).data;
1028 break;
1029 case 0x0078:
1030 info.state = (*it).data;
1031 break;
1032 case 0x0082:
1033 info.zip = (*it).data;
1034 break;
1035 case 0x008C:
1036 {
1037 Buffer b( (*it).data );
1038 info.country = b.getDWord();
1039 }
1040 break;
1041 default:
1042 kDebug(OSCAR_RAW_DEBUG) << "Unhandled tlv: " << hex << (*it).type << " data: " << hex << (*it).data;
1043 break;
1044 }
1045 }
1046 infoList.append( info );
1047 }
1048 return infoList;
1049 }
1050
storeAddressItemList(const ICQFullInfo::AddressItemList & infoList) const1051 QByteArray ICQFullInfo::storeAddressItemList( const ICQFullInfo::AddressItemList& infoList ) const
1052 {
1053 Buffer buffer;
1054
1055 buffer.addWord( infoList.count() );
1056 for ( int i = 0; i < infoList.count(); i++ )
1057 {
1058 const AddressItem& info = infoList.at( i );
1059
1060 buffer.startBlock( Buffer::BWord );
1061 buffer.addTLV( 0x0064, info.address );
1062 buffer.addTLV( 0x006E, info.city );
1063 buffer.addTLV( 0x0078, info.state );
1064 buffer.addTLV( 0x0082, info.zip );
1065 buffer.addTLV32( 0x008C, info.country );
1066 buffer.endBlock();
1067 }
1068 return buffer.buffer();
1069 }
1070
parseWorkItemList(const QByteArray & data) const1071 ICQFullInfo::WorkItemList ICQFullInfo::parseWorkItemList( const QByteArray& data ) const
1072 {
1073 Buffer buffer( data );
1074 WorkItemList infoList;
1075
1076 int count = buffer.getWord();
1077 while ( (count--) > 0 )
1078 {
1079 QList<TLV> tlvList = Buffer( buffer.getBSTR() ).getTLVList();
1080
1081 WorkItem info;
1082 QList<TLV>::const_iterator it;
1083 for ( it = tlvList.constBegin(); it != tlvList.constEnd(); ++it )
1084 {
1085 switch ( (*it).type )
1086 {
1087 case 0x0064:
1088 info.position = (*it).data;
1089 break;
1090 case 0x006E:
1091 info.companyName = (*it).data;
1092 break;
1093 case 0x007D:
1094 info.department = (*it).data;
1095 break;
1096 case 0x0078:
1097 info.homepage = (*it).data;
1098 break;
1099 case 0x0082:
1100 break;
1101 case 0x008C:
1102 break;
1103 case 0x0096:
1104 break;
1105 case 0x00A0:
1106 break;
1107 case 0x00AA:
1108 info.address = (*it).data;
1109 break;
1110 case 0x00B4:
1111 info.city = (*it).data;
1112 break;
1113 case 0x00BE:
1114 info.state = (*it).data;
1115 break;
1116 case 0x00C8:
1117 info.zip = (*it).data;
1118 break;
1119 case 0x00D2:
1120 {
1121 Buffer b( (*it).data );
1122 info.country = b.getDWord();
1123 break;
1124 }
1125 default:
1126 kDebug(OSCAR_RAW_DEBUG) << "Unhandled tlv: " << hex << (*it).type << " data: " << hex << (*it).data;
1127 break;
1128 }
1129 }
1130 infoList.append( info );
1131 }
1132 return infoList;
1133 }
1134
storeWorkItemList(const ICQFullInfo::WorkItemList & infoList) const1135 QByteArray ICQFullInfo::storeWorkItemList( const ICQFullInfo::WorkItemList& infoList ) const
1136 {
1137 Buffer buffer;
1138
1139 buffer.addWord( infoList.count() );
1140 for ( int i = 0; i < infoList.count(); i++ )
1141 {
1142 const WorkItem& info = infoList.at( i );
1143
1144 buffer.startBlock( Buffer::BWord );
1145 buffer.addTLV( 0x0064, info.position );
1146 buffer.addTLV( 0x006E, info.companyName );
1147 buffer.addTLV( 0x007D, info.department );
1148 buffer.addTLV( 0x0078, info.homepage );
1149 buffer.addTLV16( 0x0082, 0x0000 );
1150 buffer.addTLV16( 0x008C, 0x0000 );
1151 buffer.addTLV( 0x0096, QByteArray( 8, '\0') );
1152 buffer.addTLV( 0x00A0, QByteArray( 8, '\0') );
1153 buffer.addTLV( 0x00AA, info.address );
1154 buffer.addTLV( 0x00B4, info.city );
1155 buffer.addTLV( 0x00BE, info.state );
1156 buffer.addTLV( 0x00C8, info.zip );
1157 buffer.addTLV32( 0x00D2, info.country );
1158 buffer.endBlock();
1159 }
1160 return buffer.buffer();
1161 }
1162
parseInfoItemList(const QByteArray & data) const1163 ICQFullInfo::InfoItemList ICQFullInfo::parseInfoItemList( const QByteArray& data ) const
1164 {
1165 Buffer buffer( data );
1166 InfoItemList infoList;
1167
1168 int count = buffer.getWord();
1169 while ( (count--) > 0 )
1170 {
1171 QList<TLV> tlvList = Buffer( buffer.getBSTR() ).getTLVList();
1172
1173 InfoItem info;
1174 QList<TLV>::const_iterator it;
1175 for ( it = tlvList.constBegin(); it != tlvList.constEnd(); ++it )
1176 {
1177 switch ( (*it).type )
1178 {
1179 case 0x0064:
1180 info.description = (*it).data;
1181 break;
1182 case 0x006E:
1183 {
1184 Buffer b( (*it).data );
1185 info.category = b.getWord();
1186 }
1187 break;
1188 default:
1189 kDebug(OSCAR_RAW_DEBUG) << "Unhandled tlv: " << hex << (*it).type << " data: " << hex << (*it).data;
1190 break;
1191 }
1192 }
1193 infoList.append( info );
1194 }
1195 return infoList;
1196 }
1197
storeInfoItemList(const ICQFullInfo::InfoItemList & infoList) const1198 QByteArray ICQFullInfo::storeInfoItemList( const ICQFullInfo::InfoItemList& infoList ) const
1199 {
1200 Buffer buffer;
1201
1202 buffer.addWord( infoList.count() );
1203 for ( int i = 0; i < infoList.count(); i++ )
1204 {
1205 const InfoItem& info = infoList.at( i );
1206
1207 buffer.startBlock( Buffer::BWord );
1208 buffer.addTLV( 0x0064, info.description );
1209 buffer.addTLV16( 0x006E, info.category );
1210 buffer.endBlock();
1211 }
1212 return buffer.buffer();
1213 }
1214
1215