/* Kopete Oscar Protocol - Chat Navigation service handlers Copyright (c) 2005 Matt Rogers Kopete (c) 2002-2005 by the Kopete developers ************************************************************************* * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * ************************************************************************* */ #include "chatnavservicetask.h" #include #include "transfer.h" #include "buffer.h" #include "task.h" #include "client.h" #include "connection.h" ChatNavServiceTask::ChatNavServiceTask( Task* parent ) : Task( parent ) { m_type = Limits; } ChatNavServiceTask::~ChatNavServiceTask() { } void ChatNavServiceTask::setRequestType( RequestType rt ) { m_type = rt; } ChatNavServiceTask::RequestType ChatNavServiceTask::requestType() { return m_type; } TQValueList ChatNavServiceTask::exchangeList() const { return m_exchanges; } bool ChatNavServiceTask::forMe( const Transfer* transfer ) const { const SnacTransfer* st = dynamic_cast( transfer ); if ( !st ) return false; if ( st->snacService() == 0x000D && st->snacSubtype() == 0x0009 ) return true; return false; } bool ChatNavServiceTask::take( Transfer* transfer ) { if ( !forMe( transfer ) ) return false; setTransfer( transfer ); Buffer* b = transfer->buffer(); while ( b->length() > 0 ) { TLV t = b->getTLV(); switch ( t.type ) { case 0x0001: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "got chat redirect TLV" << endl; break; case 0x0002: { kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "got max concurrent rooms TLV" << endl; Buffer tlvTwo(t.data); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "max concurrent rooms is " << tlvTwo.getByte() << endl; break; } case 0x0003: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "exchange info TLV found" << endl; handleExchangeInfo( t ); //set the exchanges for the client emit haveChatExchanges( m_exchanges ); break; case 0x0004: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "room info TLV found" << endl; handleBasicRoomInfo( t ); break; }; } setSuccess( 0, TQString() ); setTransfer( 0 ); return true; } void ChatNavServiceTask::onGo() { FLAP f = { 0x02, 0, 0x00 }; SNAC s = { 0x000D, (unsigned short)m_type, 0x0000, client()->snacSequence() }; Buffer* b = new Buffer(); Transfer* t = createTransfer( f, s, b ); send( t ); } void ChatNavServiceTask::createRoom( WORD exchange, const TQString& name ) { //most of this comes from pidgin. thanks to them for figuring it out TQString cookie = "create"; //hardcoded, seems to be ignored by AOL TQString lang = "en"; TQString charset = "us-ascii"; FLAP f = { 0x02, 0, 0 }; SNAC s = { 0x000D, 0x0008, 0x0000, client()->snacSequence() }; Buffer *b = new Buffer; b->addWord( exchange ); b->addBUIN( cookie.latin1() ); b->addWord( 0xFFFF ); //assign the last instance b->addByte( 0x01 ); //detail level //just send three TLVs b->addWord( 0x0003 ); //i'm lazy, add TLVs manually b->addWord( 0x00D3 ); //type of 0x00D3 - name b->addWord( name.length() ); b->addString( name.latin1(), name.length() ); b->addWord( 0x00D6 ); //type of 0x00D6 - charset b->addWord( charset.length() ); b->addString( charset.latin1(), charset.length() ); b->addWord( 0x00D7 ); //type of 0x00D7 - lang b->addWord( lang.length() ); b->addString( lang.latin1(), lang.length() ); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "sending join room packet" << endl; Transfer* t = createTransfer( f, s, b ); send( t ); } void ChatNavServiceTask::handleExchangeInfo( const TLV& t ) { kdDebug(OSCAR_RAW_DEBUG) << "Parsing exchange info TLV" << endl; Buffer b(t.data); ChatExchangeInfo exchangeInfo; exchangeInfo.number = b.getWord(); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "exchange id is: " << exchangeInfo.number << endl; b.getWord(); while ( b.length() > 0 ) { TLV t = b.getTLV(); Buffer tmp = t.data; switch (t.type) { case 0x02: //kdDebug(OSCAR_RAW_DEBUG) << "user class is " << t.data << endl; break; case 0x03: exchangeInfo.maxRooms = tmp.getWord(); kdDebug(OSCAR_RAW_DEBUG) << "max concurrent rooms for the exchange is " << t.data << endl; break; case 0x04: exchangeInfo.maxRoomNameLength = tmp.getWord(); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "max room name length is " << exchangeInfo.maxRoomNameLength << endl; break; case 0x05: //kdDebug(OSCAR_RAW_DEBUG) << "received root rooms info" << endl; break; case 0x06: //kdDebug(OSCAR_RAW_DEBUG) << "received search tags" << endl; break; case 0xCA: //kdDebug(OSCAR_RAW_DEBUG) << "have exchange creation time" << endl; break; case 0xC9: //kdDebug(OSCAR_RAW_DEBUG) << "got chat flag" << endl; break; case 0xD0: //kdDebug(OSCAR_RAW_DEBUG) << "got mandantory channels" << endl; break; case 0xD1: exchangeInfo.maxMsgLength = tmp.getWord(); kdDebug(OSCAR_RAW_DEBUG) << "max message length" << t.data << endl; break; case 0xD2: kdDebug(OSCAR_RAW_DEBUG) << "max occupancy" << t.data << endl; break; case 0xD3: { TQString eName( t.data ); kdDebug(OSCAR_RAW_DEBUG) << "exchange name: " << eName << endl; exchangeInfo.description = eName; break; } case 0xD4: //kdDebug(OSCAR_RAW_DEBUG) << "got optional channels" << endl; break; case 0xD5: exchangeInfo.canCreate = tmp.getByte(); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "creation permissions " << exchangeInfo.canCreate << endl; break; default: kdDebug(OSCAR_RAW_DEBUG) << "unknown TLV type " << t.type << endl; break; } } m_exchanges.append( exchangeInfo.number ); } void ChatNavServiceTask::handleBasicRoomInfo( const TLV& t ) { kdDebug(OSCAR_RAW_DEBUG) << "Parsing room info TLV" << t.length << endl; Buffer b(t.data); WORD exchange = b.getWord(); TQByteArray cookie( b.getBlock( b.getByte() ) ); WORD instance = b.getWord(); b.getByte(); //detail level, which i'm not sure we need WORD tlvCount = b.getWord(); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "e: " << exchange << " c: " << cookie << " i: " << instance << endl; TQValueList tlvList = b.getTLVList(); TQValueList::iterator it, itEnd = tlvList.end(); TQString roomName; for ( it = tlvList.begin(); it != itEnd; ++it ) { TLV t = ( *it ); switch (t.type) { case 0x66: kdDebug(OSCAR_RAW_DEBUG) << "user class is " << t.data << endl; break; case 0x67: kdDebug(OSCAR_RAW_DEBUG) << "user array" << endl; break; case 0x68: kdDebug(OSCAR_RAW_DEBUG) << "evil generated" << t.data << endl; break; case 0x69: kdDebug(OSCAR_RAW_DEBUG) << "evil generated array" << endl; break; case 0x6A: roomName = TQString( t.data ); kdDebug(OSCAR_RAW_DEBUG) << "fully qualified name" << roomName << endl; break; case 0x6B: kdDebug(OSCAR_RAW_DEBUG) << "moderator" << endl; break; case 0x6D: kdDebug(OSCAR_RAW_DEBUG) << "num children" << endl; break; case 0x06F: kdDebug(OSCAR_RAW_DEBUG) << "occupancy" << endl; break; case 0x71: kdDebug(OSCAR_RAW_DEBUG) << "occupant evil" << endl; break; case 0x75: kdDebug(OSCAR_RAW_DEBUG) << "room activity" << endl; break; case 0xD0: kdDebug(OSCAR_RAW_DEBUG) << "got mandantory channels" << endl; break; case 0xD1: kdDebug(OSCAR_RAW_DEBUG) << "max message length" << t.data << endl; break; case 0xD2: kdDebug(OSCAR_RAW_DEBUG) << "max occupancy" << t.data << endl; break; case 0xD3: kdDebug(OSCAR_RAW_DEBUG) << "exchange name" << endl; break; case 0xD4: kdDebug(OSCAR_RAW_DEBUG) << "got optional channels" << endl; break; case 0xD5: kdDebug(OSCAR_RAW_DEBUG) << "creation permissions " << t.data << endl; break; default: kdDebug(OSCAR_RAW_DEBUG) << "unknown TLV type " << t.type << endl; break; } } emit connectChat( exchange, cookie, instance, roomName ); } void ChatNavServiceTask::handleCreateRoomInfo( const TLV& t ) { Buffer b( t.data ); WORD exchange = b.getWord(); WORD cookieLength = b.getByte(); TQByteArray cookie( b.getBlock( cookieLength ) ); WORD instance = b.getWord(); BYTE detailLevel = b.getByte(); if ( detailLevel != 0x02 ) { kdWarning(OSCAR_RAW_DEBUG) << k_funcinfo << "unknown detail level in response" << endl; return; } WORD numberTlvs = b.getWord(); TQValueList roomTLVList = b.getTLVList(); TQValueList::iterator itEnd = roomTLVList.end(); for ( TQValueList::iterator it = roomTLVList.begin(); it != itEnd; ++ it ) { switch( ( *it ).type ) { case 0x006A: { TQString fqcn = TQString( ( *it ).data ); kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "fqcn: " << fqcn << endl; break; } case 0x00C9: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "flags: " << t.data << endl; break; case 0x00CA: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "create time: " << t.data << endl; break; case 0x00D1: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "max msg len: " << t.data << endl; break; case 0x00D2: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "max occupancy: " << t.data << endl; break; case 0x00D3: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "name: " << TQString( t.data ) << endl; break; case 0x00D5: kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "create perms: " << t.data << endl; break; }; } } #include "chatnavservicetask.moc"