1 // Kopete Oscar Protocol - Server redirections
2 
3 // Copyright (C)  2005  Matt Rogers <mattr@kde.org>
4 
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 // Lesser General Public License for more details.
14 
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301  USA
19 
20 #include "serverredirecttask.h"
21 
22 #include <kdebug.h>
23 
24 #include "buffer.h"
25 #include "connection.h"
26 #include "transfer.h"
27 
ServerRedirectTask(Task * parent)28 ServerRedirectTask::ServerRedirectTask( Task* parent )
29 	:Task( parent ),  m_service( 0 )
30 {
31 
32 }
33 
setService(Oscar::WORD family)34 void ServerRedirectTask::setService( Oscar::WORD family )
35 {
36 	m_service = family;
37 }
38 
setChatParams(Oscar::WORD exchange,QByteArray cookie,Oscar::WORD instance)39 void ServerRedirectTask::setChatParams( Oscar::WORD exchange, QByteArray cookie, Oscar::WORD instance )
40 {
41     m_chatExchange = exchange;
42     m_chatCookie = cookie;
43     kDebug(OSCAR_RAW_DEBUG) << "cookie is" << m_chatCookie;
44     m_chatInstance = instance;
45 }
46 
setChatRoom(const QString & roomName)47 void ServerRedirectTask::setChatRoom( const QString& roomName )
48 {
49     m_chatRoom = roomName;
50 }
51 
onGo()52 void ServerRedirectTask::onGo()
53 {
54 	if ( m_service != 0 )
55 		requestNewService();
56 }
57 
forMe(const Transfer * transfer) const58 bool ServerRedirectTask::forMe( const Transfer* transfer ) const
59 {
60 	const SnacTransfer* st = dynamic_cast<const SnacTransfer*>( transfer );
61 	if ( !st )
62 		return false;
63 
64 	if ( st->snacService() == 1 && st->snacSubtype() == 0x0005 )
65 		return true;
66 	else
67 		return false;
68 }
69 
take(Transfer * transfer)70 bool ServerRedirectTask::take( Transfer* transfer )
71 {
72 	if ( !forMe( transfer ) )
73 		return false;
74 
75 	setTransfer( transfer );
76     bool value = handleRedirect();
77     setSuccess( 0, QString() );
78     setTransfer( 0 );
79 	return value;
80 }
81 
requestNewService()82 void ServerRedirectTask::requestNewService()
83 {
84 	FLAP f = { 0x02, 0, 0x00 };
85 	SNAC s = { 0x0001, 0x0004, 0x0000, client()->snacSequence() };
86 	Buffer* b = new Buffer();
87 	b->addWord( m_service );
88     kDebug(OSCAR_RAW_DEBUG) << "Requesting server for service " << m_service;
89     if ( m_service == 0x000E )
90     {
91         b->addWord( 0x0001 );
92         b->addWord( m_chatCookie.size() + 5 );
93         b->addWord( m_chatExchange );
94         b->addByte( m_chatCookie.size() );
95         b->addString( m_chatCookie );
96         b->addWord( m_chatInstance );
97     }
98 
99     Transfer* t = createTransfer( f, s, b );
100     send( t );
101 }
102 
handleRedirect()103 bool ServerRedirectTask::handleRedirect()
104 {
105 	//TLVs 0x0D, 0x05, 0x06
106 	//family id
107 	//server
108 	//auth cookie
109 	Buffer* b = transfer()->buffer();
110 	Oscar::WORD typeD = b->getWord();
111 	Oscar::WORD typeDLen = b->getWord();
112 	if ( typeD == 0x000D && typeDLen == 0x0002)
113 	{
114         Oscar::WORD realService = b->getWord();
115 		if ( realService != m_service )
116 		{
117 			kDebug(OSCAR_RAW_DEBUG) << "wrong service for this task";
118 			kDebug(OSCAR_RAW_DEBUG ) << "should be " << m_service << " is "
119 			                          << realService << endl;
120 			return false;
121 		}
122 	}
123 	else
124 		return false;
125 
126 	TLV server = b->getTLV();
127 	m_newHost = QString( server.data );
128 	kDebug(OSCAR_RAW_DEBUG) << "Host for service " << m_service
129 	                         << " is " << m_newHost << endl;
130 	if ( m_newHost.isEmpty() )
131 		return false;
132 
133 	TLV cookie = b->getTLV();
134 
135 	if ( cookie.length == 0 || cookie.data.isEmpty() )
136 		return false;
137 	else
138 		m_cookie = cookie.data;
139 
140 	emit haveServer( m_newHost, m_cookie, m_service );
141 	return true;
142 }
143 
cookie() const144 QByteArray ServerRedirectTask::cookie() const
145 {
146 	return m_cookie;
147 }
148 
newHost() const149 QString ServerRedirectTask::newHost() const
150 {
151 	return m_newHost;
152 }
153 
service() const154 Oscar::WORD ServerRedirectTask::service() const
155 {
156 	return m_service;
157 }
158 
chatExchange() const159 Oscar::WORD ServerRedirectTask::chatExchange() const
160 {
161     return m_chatExchange;
162 }
163 
chatRoomName() const164 QString ServerRedirectTask::chatRoomName() const
165 {
166     return m_chatRoom;
167 }
168 
169