~ubuntu-branches/ubuntu/quantal/psi/quantal

« back to all changes in this revision

Viewing changes to cutestuff/rtsp/rtspproxy.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2005-01-10 17:41:43 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050110174143-ltocv5zapl6blf5d
Tags: 0.9.3-1
* New upstream release
* Cleaned up debian/rules (some things are done by upstream Makefiles now)
* Fixed some lintian warnings:
  - removed executable bit from some .png files
  - moved psi.desktop to /usr/share/applications
* Updated menu files

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * rtspproxy.cpp - proxy for RTSP allowing direct and/or virtual endpoints
 
3
 * Copyright (C) 2004  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 "rtspproxy.h"
 
22
 
 
23
#include <qurl.h>
 
24
#include "servsock.h"
 
25
#include "bsocket.h"
 
26
#include "rtspbase.h"
 
27
#include "altports.h"
 
28
 
 
29
#define SERVER_ALLOC_BASE 16000
 
30
#define SERVER_ALLOC_MAX  65535
 
31
 
 
32
static bool try_serve(RTSP::Server *s)
 
33
{
 
34
        for(int n = SERVER_ALLOC_BASE; n <= SERVER_ALLOC_MAX; ++n)
 
35
        {
 
36
                if(s->start(n))
 
37
                        return true;
 
38
        }
 
39
        return false;
 
40
}
 
41
 
 
42
//----------------------------------------------------------------------------
 
43
// PortMapper
 
44
//----------------------------------------------------------------------------
 
45
static PortRangeList create_virtual_ranges(const PortRangeList &in)
 
46
{
 
47
        PortRangeList out;
 
48
        int base = 1;
 
49
        for(PortRangeList::ConstIterator it = in.begin(); it != in.end(); ++it)
 
50
        {
 
51
                PortRange r;
 
52
                r.base = base;
 
53
                r.count = (*it).count;
 
54
                base += r.count;
 
55
                out.append(r);
 
56
        }
 
57
        return out;
 
58
}
 
59
 
 
60
class MapItem
 
61
{
 
62
public:
 
63
        bool active;
 
64
        bool virt;
 
65
        QHostAddress host;
 
66
        PortRange realPorts;
 
67
        AltPorts altPorts;
 
68
        PortRangeList realPortRanges, altPortRanges;
 
69
 
 
70
        MapItem()
 
71
        {
 
72
                active = false;
 
73
                virt = false;
 
74
        }
 
75
 
 
76
        void reset()
 
77
        {
 
78
                active = false;
 
79
                virt = false;
 
80
                host = QHostAddress();
 
81
                altPorts.reset();
 
82
        }
 
83
};
 
84
 
 
85
class PortMapper : public QObject
 
86
{
 
87
        Q_OBJECT
 
88
public:
 
89
        PortMapper();
 
90
        ~PortMapper();
 
91
 
 
92
        void reset();
 
93
 
 
94
        // setup
 
95
        bool reserveDirectClient(const PortRangeList &clientRanges, bool virtServer=false);
 
96
        bool reserveVirtualClient(const PortRangeList &clientRanges);
 
97
        bool finalize(const QHostAddress &clientHost, const PortRange &clientPorts, const QHostAddress &serverHost, const PortRange &serverPorts);
 
98
 
 
99
        PortRangeList clientAlternatePorts() const;
 
100
        PortRangeList serverAlternatePorts() const;
 
101
 
 
102
        void writeAsClient(int source, int dest, const QByteArray &buf);
 
103
        void writeAsServer(int source, int dest, const QByteArray &buf);
 
104
 
 
105
signals:
 
106
        void packetFromClient(int source, int dest, const QByteArray &buf);
 
107
        void packetFromServer(int source, int dest, const QByteArray &buf);
 
108
 
 
109
private slots:
 
110
        void client_packetReady(int index, const QHostAddress &addr, int sourcePort, const QByteArray &buf);
 
111
        void server_packetReady(int index, const QHostAddress &addr, int sourcePort, const QByteArray &buf);
 
112
 
 
113
private:
 
114
        MapItem client, server;
 
115
        bool ready;
 
116
};
 
117
 
 
118
PortMapper::PortMapper()
 
119
{
 
120
        connect(&client.altPorts, SIGNAL(packetReady(int, const QHostAddress &, int, const QByteArray &)), SLOT(client_packetReady(int, const QHostAddress &, int, const QByteArray &)));
 
121
        connect(&server.altPorts, SIGNAL(packetReady(int, const QHostAddress &, int, const QByteArray &)), SLOT(server_packetReady(int, const QHostAddress &, int, const QByteArray &)));
 
122
        ready = false;
 
123
}
 
124
 
 
125
PortMapper::~PortMapper()
 
126
{
 
127
}
 
128
 
 
129
void PortMapper::reset()
 
130
{
 
131
        client.reset();
 
132
        server.reset();
 
133
        ready = false;
 
134
}
 
135
 
 
136
bool PortMapper::reserveDirectClient(const PortRangeList &clientRanges, bool virtServer)
 
137
{
 
138
        if(client.active)
 
139
                return true;
 
140
 
 
141
        client.realPortRanges = clientRanges;
 
142
        if(virtServer)
 
143
        {
 
144
                client.virt = true; // virtual server means virtual client ports
 
145
                client.altPortRanges = create_virtual_ranges(clientRanges);
 
146
        }
 
147
        else
 
148
        {
 
149
                if(!client.altPorts.reserve(clientRanges, &client.altPortRanges))
 
150
                        return false;
 
151
        }
 
152
        client.active = true;
 
153
 
 
154
        return true;
 
155
}
 
156
 
 
157
bool PortMapper::reserveVirtualClient(const PortRangeList &clientRanges)
 
158
{
 
159
        if(client.active)
 
160
                return false;
 
161
 
 
162
        server.virt = true; // virtual client means virtual server ports
 
163
        client.realPortRanges = clientRanges;
 
164
        client.altPorts.reserve(clientRanges, &client.altPortRanges);
 
165
        client.active = true;
 
166
 
 
167
        return true;
 
168
}
 
169
 
 
170
bool PortMapper::finalize(const QHostAddress &clientHost, const PortRange &clientPorts, const QHostAddress &serverHost, const PortRange &serverPorts)
 
171
{
 
172
        if(ready)
 
173
                return true;
 
174
 
 
175
        int n = client.altPortRanges.findByBase(clientPorts.base);
 
176
        if(n == -1)
 
177
                return false;
 
178
 
 
179
        client.host = clientHost;
 
180
        client.realPorts = client.realPortRanges[n];
 
181
        client.realPorts.count = clientPorts.count;
 
182
 
 
183
        if(client.virt)
 
184
        {
 
185
                PortRange virtPorts = client.altPortRanges[n];
 
186
                virtPorts.count = clientPorts.count;
 
187
                client.altPortRanges.clear();
 
188
                client.altPortRanges.append(virtPorts);
 
189
        }
 
190
        else
 
191
        {
 
192
                client.altPorts.keep(client.realPorts);
 
193
                client.altPortRanges.clear();
 
194
                client.altPortRanges.append(client.altPorts.range());
 
195
        }
 
196
 
 
197
        server.host = serverHost;
 
198
        server.realPorts = serverPorts;
 
199
 
 
200
        if(server.virt)
 
201
        {
 
202
                PortRangeList in;
 
203
                in.append(server.realPorts);
 
204
                server.altPortRanges = create_virtual_ranges(in);
 
205
        }
 
206
        else
 
207
        {
 
208
                PortRange r;
 
209
                if(!server.altPorts.allocate(server.realPorts, &r))
 
210
                        return false;
 
211
                server.altPortRanges.clear();
 
212
                server.altPortRanges.append(r);
 
213
        }
 
214
        server.active = true;
 
215
 
 
216
        ready = true;
 
217
        return true;
 
218
}
 
219
 
 
220
PortRangeList PortMapper::clientAlternatePorts() const
 
221
{
 
222
        return client.altPortRanges;
 
223
}
 
224
 
 
225
PortRangeList PortMapper::serverAlternatePorts() const
 
226
{
 
227
        return server.altPortRanges;
 
228
}
 
229
 
 
230
void PortMapper::writeAsClient(int source, int, const QByteArray &buf)
 
231
{
 
232
        if(source < client.realPorts.base || source >= client.realPorts.base + client.realPorts.count)
 
233
                return;
 
234
        int index = source - client.realPorts.base;
 
235
        client.altPorts.send(index, server.host, server.realPorts.base + index, buf);
 
236
}
 
237
 
 
238
void PortMapper::writeAsServer(int source, int, const QByteArray &buf)
 
239
{
 
240
        if(source < server.realPorts.base || source >= server.realPorts.base + server.realPorts.count)
 
241
                return;
 
242
        int index = source - server.realPorts.base;
 
243
        server.altPorts.send(index, client.host, client.realPorts.base + index, buf);
 
244
}
 
245
 
 
246
void PortMapper::client_packetReady(int index, const QHostAddress &, int, const QByteArray &buf)
 
247
{
 
248
        if(server.virt)
 
249
                emit packetFromServer(server.altPortRanges.first().base + index, client.realPorts.base + index, buf);
 
250
        else
 
251
                server.altPorts.send(index, client.host, client.realPorts.base + index, buf);
 
252
}
 
253
 
 
254
void PortMapper::server_packetReady(int index, const QHostAddress &, int, const QByteArray &buf)
 
255
{
 
256
        if(client.virt)
 
257
                emit packetFromClient(client.altPortRanges.first().base + index, server.realPorts.base + index, buf);
 
258
        else
 
259
                client.altPorts.send(index, server.host, server.realPorts.base + index, buf);
 
260
}
 
261
 
 
262
//----------------------------------------------------------------------------
 
263
// Session
 
264
//----------------------------------------------------------------------------
 
265
using namespace RTSP;
 
266
 
 
267
static PortRangeList transport_get_ports(const TransportList &list, const QString &type)
 
268
{
 
269
        PortRangeList out;
 
270
        for(TransportList::ConstIterator it = list.begin(); it != list.end(); ++it)
 
271
        {
 
272
                PortRange r;
 
273
                if(!r.fromString((*it).argument(type)))
 
274
                        continue;
 
275
                out.merge(r);
 
276
        }
 
277
        return out;
 
278
}
 
279
 
 
280
static TransportList transport_set_ports(const TransportList &_list, const QString &type, const PortRangeList &newpl)
 
281
{
 
282
        TransportList list = _list;
 
283
        PortRangeList oldpl = transport_get_ports(_list, type);
 
284
        for(TransportList::Iterator it = list.begin(); it != list.end(); ++it)
 
285
        {
 
286
                Transport &t = *it;
 
287
                PortRange r;
 
288
                if(!r.fromString(t.argument(type)))
 
289
                        continue;
 
290
                int n = oldpl.findByBase(r.base);
 
291
                if(n == -1)
 
292
                        continue;
 
293
                r.base = newpl[n].base;
 
294
                t.setArgument(type, r.toString());
 
295
        }
 
296
        return list;
 
297
}
 
298
 
 
299
static PortRangeList transport_get_client_ports(const TransportList &list)
 
300
{
 
301
        return transport_get_ports(list, "client_port");
 
302
}
 
303
 
 
304
static TransportList transport_set_client_ports(const TransportList &_list, const PortRangeList &newpl)
 
305
{
 
306
        return transport_set_ports(_list, "client_port", newpl);
 
307
}
 
308
 
 
309
static PortRangeList transport_get_server_ports(const TransportList &list)
 
310
{
 
311
        return transport_get_ports(list, "server_port");
 
312
}
 
313
 
 
314
static TransportList transport_set_server_ports(const TransportList &_list, const PortRangeList &newpl)
 
315
{
 
316
        return transport_set_ports(_list, "server_port", newpl);
 
317
}
 
318
 
 
319
static void showPacket(const RTSP::Packet &p)
 
320
{
 
321
        if(p.type() == RTSP::Packet::Request)
 
322
        {
 
323
                printf("--- RTSP Request     ---\n");
 
324
                printf("Command:  [%s]\n", p.command().latin1());
 
325
                printf("Resource: [%s]\n", p.resource().latin1());
 
326
                printf("Version:  [%s]\n", p.version().latin1());
 
327
                printf("Headers:\n");
 
328
                HeaderList headers = p.headers();
 
329
                for(HeaderList::ConstIterator it = headers.begin(); it != headers.end(); ++it)
 
330
                        printf("  [%s] = [%s]\n", (*it).name.latin1(), (*it).value.latin1());
 
331
                QByteArray data = p.data();
 
332
                if(!data.isEmpty())
 
333
                        printf("[%d bytes of attached content]\n", data.size());
 
334
                printf("------------------------\n");
 
335
        }
 
336
        else if(p.type() == RTSP::Packet::Response)
 
337
        {
 
338
                printf("--- RTSP Response    ---\n");
 
339
                printf("Code:     [%d]\n", p.responseCode());
 
340
                printf("String:   [%s]\n", p.responseString().latin1());
 
341
                printf("Version:  [%s]\n", p.version().latin1());
 
342
                printf("Headers:\n");
 
343
                HeaderList headers = p.headers();
 
344
                for(HeaderList::ConstIterator it = headers.begin(); it != headers.end(); ++it)
 
345
                        printf("  [%s] = [%s]\n", (*it).name.latin1(), (*it).value.latin1());
 
346
                QByteArray data = p.data();
 
347
                if(!data.isEmpty())
 
348
                        printf("[%d bytes of attached content]\n", data.size());
 
349
                printf("------------------------\n");
 
350
        }
 
351
        else if(p.type() == RTSP::Packet::Data)
 
352
        {
 
353
                printf("--- RTSP Interleaved ---\n");
 
354
                printf("Channel:  [%d]\n", p.channel());
 
355
                QByteArray data = p.data();
 
356
                if(!data.isEmpty())
 
357
                        printf("[%d bytes of RTP content]\n", data.size());
 
358
                printf("------------------------\n");
 
359
        }
 
360
}
 
361
 
 
362
class Session : public QObject
 
363
{
 
364
        Q_OBJECT
 
365
public:
 
366
        Session()
 
367
        {
 
368
                client = 0;
 
369
                server = 0;
 
370
 
 
371
                connect(&local, SIGNAL(incomingReady()), SLOT(local_incomingReady()));
 
372
                connect(&mapper, SIGNAL(packetFromClient(int, int, const QByteArray &)), SLOT(map_packetFromClient(int, int, const QByteArray &)));
 
373
                connect(&mapper, SIGNAL(packetFromServer(int, int, const QByteArray &)), SLOT(map_packetFromServer(int, int, const QByteArray &)));
 
374
        }
 
375
 
 
376
        ~Session()
 
377
        {
 
378
                reset();
 
379
        }
 
380
 
 
381
        void reset()
 
382
        {
 
383
                delete client;
 
384
                client = 0;
 
385
                delete server;
 
386
                server = 0;
 
387
        }
 
388
 
 
389
        bool startIncoming(const QValueList<QUrl> &_urls, ByteStream *_server, int *incomingPort)
 
390
        {
 
391
                urls = _urls;
 
392
                server = new RTSP::Client;
 
393
                server->setByteStream(_server, RTSP::Client::MServer);
 
394
 
 
395
                if(!try_serve(&local))
 
396
                        return false;
 
397
 
 
398
                virtClient = false;
 
399
                virtServer = true;
 
400
                *incomingPort = local.port();
 
401
                return true;
 
402
        }
 
403
 
 
404
        bool startIncoming(const QValueList<QUrl> &_urls, const QString &serverHost, int serverPort, int *incomingPort)
 
405
        {
 
406
                if(_urls.isEmpty())
 
407
                        return false;
 
408
 
 
409
                urls = _urls;
 
410
                shost = serverHost;
 
411
                sport = serverPort;
 
412
 
 
413
                if(!try_serve(&local))
 
414
                        return false;
 
415
 
 
416
                virtClient = false;
 
417
                virtServer = false;
 
418
                *incomingPort = local.port();
 
419
                return true;
 
420
        }
 
421
 
 
422
        bool startExisting(const QValueList<QUrl> &_urls, ByteStream *_client, const QString &serverHost, int serverPort)
 
423
        {
 
424
                urls = _urls;
 
425
                client = new RTSP::Client;
 
426
                client->setByteStream(_client, RTSP::Client::MClient);
 
427
                shost = serverHost;
 
428
                sport = serverPort;
 
429
 
 
430
                virtClient = true;
 
431
                virtServer = false;
 
432
                return true;
 
433
        }
 
434
 
 
435
        void writeAsClient(int source, int dest, const QByteArray &buf)
 
436
        {
 
437
                mapper.writeAsClient(source, dest, buf);
 
438
        }
 
439
 
 
440
        void writeAsServer(int source, int dest, const QByteArray &buf)
 
441
        {
 
442
                mapper.writeAsServer(source, dest, buf);
 
443
        }
 
444
 
 
445
signals:
 
446
        void packetFromClient(int source, int dest, const QByteArray &buf);
 
447
        void packetFromServer(int source, int dest, const QByteArray &buf);
 
448
 
 
449
private slots:
 
450
        void local_incomingReady()
 
451
        {
 
452
                Client *c = local.takeIncoming();
 
453
                if(!c)
 
454
                        return;
 
455
 
 
456
                local.stop();
 
457
 
 
458
                client = c;
 
459
                connect(client, SIGNAL(connectionClosed()), SLOT(client_connectionClosed()));
 
460
                connect(client, SIGNAL(packetReady(const Packet &)), SLOT(client_packetReady(const Packet &)));
 
461
                connect(client, SIGNAL(packetWritten()), SLOT(client_packetWritten()));
 
462
                connect(client, SIGNAL(error(int)), SLOT(client_error(int)));
 
463
        }
 
464
 
 
465
        void client_connectionClosed()
 
466
        {
 
467
                printf("Session: Client: connectionClosed\n");
 
468
                delete client;
 
469
                client = 0;
 
470
        }
 
471
 
 
472
        void client_packetReady(const Packet &p)
 
473
        {
 
474
                showPacket(p);
 
475
 
 
476
                Packet m = p;
 
477
                lastWasSetup = false;
 
478
 
 
479
                // unmangle the url?
 
480
                if(!virtClient)
 
481
                {
 
482
                        QUrl u = urls.first();
 
483
                        int u_port = u.hasPort() ? u.port() : 554;
 
484
 
 
485
                        QUrl pu(m.resource());
 
486
                        pu.setHost(u.host());
 
487
                        pu.setPort(u_port == 554 ? -1 : u_port);
 
488
 
 
489
                        m.setResource(pu.toString());
 
490
                }
 
491
 
 
492
                QString cmd = m.command();
 
493
                if(cmd == "SETUP")
 
494
                {
 
495
                        TransportList list = m.transports();
 
496
                        PortRangeList pl = transport_get_client_ports(list);
 
497
 
 
498
                        /*printf("SETUP ports [%d]:\n", pl.count());
 
499
                        for(PortRangeList::ConstIterator it = pl.begin(); it != pl.end(); ++it)
 
500
                                printf("[%d-%d] ", (*it).base, (*it).count);
 
501
                        printf("\n");*/
 
502
 
 
503
                        if(virtClient)
 
504
                                mapper.reserveVirtualClient(pl);
 
505
                        else
 
506
                                mapper.reserveDirectClient(pl, virtServer);
 
507
                        PortRangeList altPorts = mapper.clientAlternatePorts();
 
508
 
 
509
                        /*printf("Alternate ports [%d]:\n", altPorts.count());
 
510
                        for(PortRangeList::ConstIterator it = altPorts.begin(); it != altPorts.end(); ++it)
 
511
                                printf("[%d-%d] ", (*it).base, (*it).count);
 
512
                        printf("\n");*/
 
513
 
 
514
                        m.setTransports(transport_set_client_ports(list, altPorts));
 
515
                        lastWasSetup = true;
 
516
                }
 
517
 
 
518
                cpackets.append(m);
 
519
 
 
520
                // on receipt of first packet, connect to server if necessary
 
521
                if(!server)
 
522
                {
 
523
                        server = new Client;
 
524
                        connect(server, SIGNAL(connected()), SLOT(server_connected()));
 
525
                        connect(server, SIGNAL(connectionClosed()), SLOT(server_connectionClosed()));
 
526
                        connect(server, SIGNAL(packetReady(const Packet &)), SLOT(server_packetReady(const Packet &)));
 
527
                        connect(server, SIGNAL(packetWritten()), SLOT(server_packetWritten()));
 
528
                        connect(server, SIGNAL(error(int)), SLOT(server_error(int)));
 
529
                        printf("Session: Server: connecting to server\n");
 
530
                        server->connectToHost(shost, sport);
 
531
                        return;
 
532
                }
 
533
 
 
534
                sendPackets();
 
535
        }
 
536
 
 
537
        void client_packetWritten()
 
538
        {
 
539
                //printf("Session: Client: packetWritten\n");
 
540
        }
 
541
 
 
542
        void client_error(int x)
 
543
        {
 
544
                printf("Session: Client: error %d\n", x);
 
545
                delete client;
 
546
                client = 0;
 
547
        }
 
548
 
 
549
        void server_connected()
 
550
        {
 
551
                printf("Session: Server: connected\n");
 
552
                sendPackets();
 
553
        }
 
554
 
 
555
        void server_connectionClosed()
 
556
        {
 
557
                printf("Session: Server: connectionClosed\n");
 
558
                reset();
 
559
        }
 
560
 
 
561
        void server_packetReady(const Packet &p)
 
562
        {
 
563
                showPacket(p);
 
564
                if(client)
 
565
                {
 
566
                        Packet m = p;
 
567
                        if(lastWasSetup)
 
568
                        {
 
569
                                TransportList list = m.transports();
 
570
                                PortRangeList cpl = transport_get_client_ports(list);
 
571
                                PortRangeList spl = transport_get_server_ports(list);
 
572
 
 
573
                                /*printf("SETUP ports [%d]:\n", cpl.count());
 
574
                                for(PortRangeList::ConstIterator it = cpl.begin(); it != cpl.end(); ++it)
 
575
                                        printf("[%d-%d] ", (*it).base, (*it).count);
 
576
                                printf("\n");
 
577
                                printf("Server SETUP ports [%d]:\n", spl.count());
 
578
                                for(PortRangeList::ConstIterator it = spl.begin(); it != spl.end(); ++it)
 
579
                                        printf("[%d-%d] ", (*it).base, (*it).count);
 
580
                                printf("\n");*/
 
581
 
 
582
                                mapper.finalize(client->peerAddress(), cpl.first(), server->peerAddress(), spl.first());
 
583
                                PortRangeList altPorts = mapper.serverAlternatePorts();
 
584
 
 
585
                                /*printf("Alternate ports [%d]:\n", altPorts.count());
 
586
                                for(PortRangeList::ConstIterator it = altPorts.begin(); it != altPorts.end(); ++it)
 
587
                                        printf("[%d-%d] ", (*it).base, (*it).count);
 
588
                                printf("\n");*/
 
589
 
 
590
                                m.setTransports(transport_set_server_ports(list, altPorts));
 
591
                        }
 
592
                        showPacket(m);
 
593
                        client->write(m);
 
594
                }
 
595
        }
 
596
 
 
597
        void server_packetWritten()
 
598
        {
 
599
                //printf("Session: Server: packetWritten\n");
 
600
        }
 
601
 
 
602
        void server_error(int x)
 
603
        {
 
604
                printf("Session: Server: error %d\n", x);
 
605
                reset();
 
606
        }
 
607
 
 
608
        void map_packetFromClient(int source, int dest, const QByteArray &buf)
 
609
        {
 
610
                packetFromClient(source, dest, buf);
 
611
        }
 
612
 
 
613
        void map_packetFromServer(int source, int dest, const QByteArray &buf)
 
614
        {
 
615
                packetFromServer(source, dest, buf);
 
616
        }
 
617
 
 
618
private:
 
619
        void sendPackets()
 
620
        {
 
621
                for(QValueList<Packet>::Iterator it = cpackets.begin(); it != cpackets.end();)
 
622
                {
 
623
                        showPacket(*it);
 
624
                        server->write(*it);
 
625
                        it = cpackets.remove(it);
 
626
                }
 
627
        }
 
628
 
 
629
        bool virtClient, virtServer;
 
630
        QValueList<Packet> cpackets;
 
631
        Client *client, *server;
 
632
        Server local;
 
633
        QValueList<QUrl> urls;
 
634
        QString shost;
 
635
        int sport;
 
636
        PortMapper mapper;
 
637
        bool lastWasSetup;
 
638
};
 
639
 
 
640
//----------------------------------------------------------------------------
 
641
// RTSPProxy
 
642
//----------------------------------------------------------------------------
 
643
class RTSPProxy::Private : public QObject
 
644
{
 
645
        Q_OBJECT
 
646
public:
 
647
        RTSPProxy *par;
 
648
 
 
649
        Private(RTSPProxy *_par) : par(_par)
 
650
        {
 
651
        }
 
652
};
 
653
 
 
654
RTSPProxy::RTSPProxy(QObject *parent)
 
655
:QObject(parent)
 
656
{
 
657
        d = new Private(this);
 
658
}
 
659
 
 
660
RTSPProxy::~RTSPProxy()
 
661
{
 
662
        delete d;
 
663
}
 
664
 
 
665
int RTSPProxy::startIncoming(const QStringList &urls, ByteStream *server, int *incomingPort)
 
666
{
 
667
}
 
668
 
 
669
int RTSPProxy::startIncoming(const QStringList &urls, const QString &serverHost, int serverPort, int *incomingPort)
 
670
{
 
671
        QValueList<QUrl> list;
 
672
        for(QStringList::ConstIterator it = urls.begin(); it != urls.end(); ++it)
 
673
                list.append(QUrl(*it));
 
674
        Session *s = new Session;
 
675
        if(!s->startIncoming(list, serverHost, serverPort, incomingPort))
 
676
        {
 
677
                delete s;
 
678
                return -1;
 
679
        }
 
680
        // TODO: add session to a list or something
 
681
}
 
682
 
 
683
int RTSPProxy::startExisting(const QStringList &urls, ByteStream *client, const QString &serverHost, int serverPort)
 
684
{
 
685
}
 
686
 
 
687
void RTSPProxy::stop(int id)
 
688
{
 
689
}
 
690
 
 
691
void RTSPProxy::writeAsClient(int id, int source, int dest, const QByteArray &buf)
 
692
{
 
693
}
 
694
 
 
695
void RTSPProxy::writeAsServer(int id, int source, int dest, const QByteArray &buf)
 
696
{
 
697
}
 
698
 
 
699
QString RTSPProxy::mangle(const QString &url, const QString &host, int port)
 
700
{
 
701
        QUrl u(url);
 
702
        u.setHost(host);
 
703
        u.setPort(port == 554 ? -1 : port);
 
704
        return u.toString();
 
705
}
 
706
 
 
707
#include "rtspproxy.moc"