source: psi/trunk/iris/jabber/xmpp_jidlink.cpp

Last change on this file was 2, checked in by dmik, 19 years ago

Imported original Psi 0.10 sources from Affinix

File size: 5.6 KB
Line 
1/*
2 * jidlink.cpp - establish a link between Jabber IDs
3 * Copyright (C) 2001, 2002 Justin Karneges
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include"xmpp_jidlink.h"
22
23#include<qdom.h>
24#include<qtimer.h>
25#include"im.h"
26#include"s5b.h"
27#include"xmpp_ibb.h"
28
29using namespace XMPP;
30
31//----------------------------------------------------------------------------
32// JidLink
33//----------------------------------------------------------------------------
34class JidLink::Private
35{
36public:
37 Client *client;
38 ByteStream *bs;
39 int type;
40 int state;
41 Jid peer;
42};
43
44JidLink::JidLink(Client *client)
45:QObject(client->jidLinkManager())
46{
47 d = new Private;
48 d->client = client;
49 d->bs = 0;
50
51 reset();
52}
53
54JidLink::~JidLink()
55{
56 reset(true);
57
58 delete d;
59}
60
61void JidLink::reset(bool clear)
62{
63 d->type = None;
64 d->state = Idle;
65
66 if(d->bs) {
67 unlink();
68 d->bs->close();
69 if(clear) {
70 delete d->bs;
71 d->bs = 0;
72 }
73 }
74}
75
76void JidLink::connectToJid(const Jid &jid, int type, const QDomElement &comment)
77{
78 reset(true);
79 if(type == DTCP)
80 d->bs = d->client->s5bManager()->createConnection();
81 else if(type == IBB)
82 d->bs = new IBBConnection(d->client->ibbManager());
83 else
84 return;
85
86 d->type = type;
87 d->peer = jid;
88 d->state = Connecting;
89
90 link();
91
92 if(type == DTCP) {
93 S5BConnection *c = (S5BConnection *)d->bs;
94 status(StatDTCPRequesting);
95 c->connectToJid(jid, d->client->s5bManager()->genUniqueSID(jid));
96 }
97 else {
98 IBBConnection *c = (IBBConnection *)d->bs;
99 status(StatIBBRequesting);
100 c->connectToJid(jid, comment);
101 }
102}
103
104void JidLink::link()
105{
106 if(d->type == DTCP) {
107 S5BConnection *c = (S5BConnection *)d->bs;
108 connect(c, SIGNAL(connected()), SLOT(dtcp_connected()));
109 connect(c, SIGNAL(accepted()), SLOT(dtcp_accepted()));
110 }
111 else {
112 IBBConnection *c = (IBBConnection *)d->bs;
113 connect(c, SIGNAL(connected()), SLOT(ibb_connected()));
114 }
115
116 connect(d->bs, SIGNAL(connectionClosed()), SLOT(bs_connectionClosed()));
117 connect(d->bs, SIGNAL(error(int)), SLOT(bs_error(int)));
118 connect(d->bs, SIGNAL(bytesWritten(int)), SLOT(bs_bytesWritten(int)));
119 connect(d->bs, SIGNAL(readyRead()), SLOT(bs_readyRead()));
120}
121
122void JidLink::unlink()
123{
124 d->bs->disconnect(this);
125}
126
127void JidLink::accept()
128{
129 if(d->state != WaitingForAccept)
130 return;
131
132 QTimer::singleShot(0, this, SLOT(doRealAccept()));
133}
134
135void JidLink::doRealAccept()
136{
137 if(d->type == DTCP) {
138 ((S5BConnection *)d->bs)->accept();
139 d->state = Connecting;
140 dtcp_accepted();
141 }
142 else {
143 ((IBBConnection *)d->bs)->accept();
144 d->state = Active;
145 connected();
146 }
147}
148
149bool JidLink::setStream(ByteStream *bs)
150{
151 reset(true);
152 int type = None;
153 if(bs->inherits("XMPP::S5BConnection"))
154 type = DTCP;
155 else if(bs->inherits("XMPP::IBBConnection"))
156 type = IBB;
157
158 if(type == None)
159 return false;
160
161 d->type = type;
162 d->bs = bs;
163 d->state = WaitingForAccept;
164
165 link();
166
167 if(d->type == DTCP)
168 d->peer = ((S5BConnection *)d->bs)->peer();
169 else
170 d->peer = ((IBBConnection *)d->bs)->peer();
171
172 return true;
173}
174
175int JidLink::type() const
176{
177 return d->type;
178}
179
180Jid JidLink::peer() const
181{
182 return d->peer;
183}
184
185int JidLink::state() const
186{
187 return d->state;
188}
189
190bool JidLink::isOpen() const
191{
192 if(d->state == Active)
193 return true;
194 else
195 return false;
196}
197
198void JidLink::close()
199{
200 if(d->state == Idle)
201 return;
202 reset();
203}
204
205void JidLink::write(const QByteArray &a)
206{
207 if(d->state == Active)
208 d->bs->write(a);
209}
210
211QByteArray JidLink::read(int bytes)
212{
213 if(d->bs)
214 return d->bs->read(bytes);
215 else
216 return QByteArray();
217}
218
219int JidLink::bytesAvailable() const
220{
221 if(d->bs)
222 return d->bs->bytesAvailable();
223 else
224 return 0;
225}
226
227int JidLink::bytesToWrite() const
228{
229 if(d->state == Active)
230 return d->bs->bytesToWrite();
231 else
232 return 0;
233}
234
235void JidLink::dtcp_accepted()
236{
237 status(StatDTCPAccepted);
238}
239
240void JidLink::dtcp_connected()
241{
242 d->state = Active;
243 status(StatDTCPConnected);
244 connected();
245}
246
247void JidLink::ibb_connected()
248{
249 d->state = Active;
250 status(StatIBBConnected);
251 connected();
252}
253
254void JidLink::bs_connectionClosed()
255{
256 reset();
257 connectionClosed();
258}
259
260void JidLink::bs_error(int)
261{
262 reset();
263 error(ErrConnect);
264}
265
266void JidLink::bs_readyRead()
267{
268 readyRead();
269}
270
271void JidLink::bs_bytesWritten(int x)
272{
273 bytesWritten(x);
274}
275
276
277//----------------------------------------------------------------------------
278// JidLinkManager
279//----------------------------------------------------------------------------
280class JidLinkManager::Private
281{
282public:
283 Private() {}
284
285 Client *client;
286 QPtrList<JidLink> incomingList;
287};
288
289JidLinkManager::JidLinkManager(Client *par)
290:QObject(par)
291{
292 d = new Private;
293 d->client = par;
294}
295
296JidLinkManager::~JidLinkManager()
297{
298 d->incomingList.setAutoDelete(true);
299 d->incomingList.clear();
300 delete d;
301}
302
303JidLink *JidLinkManager::takeIncoming()
304{
305 if(d->incomingList.isEmpty())
306 return 0;
307
308 JidLink *j = d->incomingList.getFirst();
309 d->incomingList.removeRef(j);
310 return j;
311}
312
313void JidLinkManager::insertStream(ByteStream *bs)
314{
315 JidLink *j = new JidLink(d->client);
316 if(j->setStream(bs))
317 d->incomingList.append(j);
318}
Note: See TracBrowser for help on using the repository browser.