~ubuntu-branches/ubuntu/trusty/digikam/trusty

« back to all changes in this revision

Viewing changes to extra/kipi-plugins/dlnaexport/extra/hupnp/src/devicehosting/devicehost/hdevicehost_ssdp_handler_p.cpp

  • Committer: Package Import Robot
  • Author(s): Rohan Garg
  • Date: 2012-11-26 18:24:20 UTC
  • mfrom: (1.9.1) (3.1.23 experimental)
  • Revision ID: package-import@ubuntu.com-20121126182420-qoy6z0nx4ai0wzcl
Tags: 4:3.0.0~beta3-0ubuntu1
* New upstream release
  - Add build-deps :  libhupnp-dev, libqtgstreamer-dev, libmagickcore-dev
* Merge from debian, remaining changes:
  - Make sure libqt4-opengl-dev, libgl1-mesa-dev and libglu1-mesa-dev only
    install on i386,amd64 and powerpc
  - Depend on libtiff-dev instead of libtiff4-dev
  - Drop digikam breaks/replaces kipi-plugins-common since we're past the
    LTS release now
  - digikam to recommend mplayerthumbs | ffmpegthumbs. We currently only
    have latter in the archives, even though former is also supposed to
    be part of kdemultimedia. (LP: #890059)
  - kipi-plugins to recommend www-browser rather than konqueror directly
    since 2.8 no direct usage of konqueror is present in the flickr
    plugin anymore (LP: #1011211)
  - Keep kubuntu_mysqld_executable_name.diff
  - Don't install libkipi translations
  - Keep deps on libcv-dev, libcvaux-dev
  - Keep split packaging of libraries
  - Replace icons from KDE 3 time in debian/xpm.d/*.xpm with the new
    versions (LP: #658047)
* Update debian/not-installed

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved.
 
3
 *
 
4
 *  Author: Tuomo Penttinen <tp@herqq.org>
 
5
 *
 
6
 *  This file is part of Herqq UPnP (HUPnP) library.
 
7
 *
 
8
 *  Herqq UPnP is free software: you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU Lesser General Public License as published by
 
10
 *  the Free Software Foundation, either version 3 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
13
 *  Herqq UPnP is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
16
 *  GNU Lesser General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU Lesser General Public License
 
19
 *  along with Herqq UPnP. If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#include "hdevicehost_ssdp_handler_p.h"
 
23
#include "hserverdevicecontroller_p.h"
 
24
 
 
25
#include "../../general/hupnp_global_p.h"
 
26
 
 
27
#include "../../dataelements/hudn.h"
 
28
#include "../../dataelements/hdeviceinfo.h"
 
29
#include "../../dataelements/hserviceinfo.h"
 
30
#include "../../dataelements/hdiscoverytype.h"
 
31
#include "../../dataelements/hproduct_tokens.h"
 
32
 
 
33
#include "../../devicemodel/hdevicestatus.h"
 
34
#include "../../devicemodel/server/hserverdevice.h"
 
35
#include "../../devicemodel/server/hserverservice.h"
 
36
 
 
37
#include "../../general/hlogger_p.h"
 
38
#include "../../utils/hsysutils_p.h"
 
39
 
 
40
#include <QtCore/QUuid>
 
41
#include <QtCore/QDateTime>
 
42
 
 
43
namespace Herqq
 
44
{
 
45
 
 
46
namespace Upnp
 
47
{
 
48
 
 
49
/*******************************************************************************
 
50
 * HDelayedWriter
 
51
 ******************************************************************************/
 
52
HDelayedWriter::HDelayedWriter(
 
53
    HDeviceHostSsdpHandler& ssdp,
 
54
    const QList<HDiscoveryResponse>& responses,
 
55
    const HEndpoint& source,
 
56
    qint32 msecs) :
 
57
        QObject(&ssdp),
 
58
            m_ssdp(ssdp), m_responses(responses), m_source(source), m_msecs(msecs)
 
59
{
 
60
}
 
61
 
 
62
void HDelayedWriter::timerEvent(QTimerEvent*)
 
63
{
 
64
    HLOG2(H_AT, H_FUN, m_ssdp.loggingIdentifier());
 
65
    foreach(const HDiscoveryResponse& resp, m_responses)
 
66
    {
 
67
        qint32 count = m_ssdp.sendDiscoveryResponse(resp, m_source);
 
68
        if (count <= 0)
 
69
        {
 
70
            HLOG_WARN(QString("Failed to send discovery response [%1] to: [%2].").arg(
 
71
                resp.usn().toString(), m_source.toString()));
 
72
        }
 
73
    }
 
74
 
 
75
    emit sent();
 
76
}
 
77
 
 
78
void HDelayedWriter::run()
 
79
{
 
80
   startTimer(m_msecs);
 
81
}
 
82
 
 
83
/*******************************************************************************
 
84
 * HDeviceHostSsdpHandler
 
85
 ******************************************************************************/
 
86
HDeviceHostSsdpHandler::HDeviceHostSsdpHandler(
 
87
    const QByteArray& loggingIdentifier,
 
88
    HDeviceStorage<HServerDevice, HServerService, HServerDeviceController>& ds,
 
89
    QObject* parent) :
 
90
        HSsdp(loggingIdentifier, parent), m_deviceStorage(ds)
 
91
{
 
92
    Q_ASSERT(parent);
 
93
    setFilter(DiscoveryRequest);
 
94
}
 
95
 
 
96
HDeviceHostSsdpHandler::~HDeviceHostSsdpHandler()
 
97
{
 
98
}
 
99
 
 
100
bool HDeviceHostSsdpHandler::processSearchRequest_specificDevice(
 
101
    const HDiscoveryRequest& req, const HEndpoint& source,
 
102
    QList<HDiscoveryResponse>* responses)
 
103
{
 
104
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
105
 
 
106
    HDiscoveryType st = req.searchTarget();
 
107
    QUuid uuid = st.udn().value();
 
108
    if (uuid.isNull())
 
109
    {
 
110
        HLOG_DBG(QString("Invalid device-UUID: [%1]").arg(st.udn().toString()));
 
111
        return false;
 
112
    }
 
113
 
 
114
    const HServerDevice* device =
 
115
        m_deviceStorage.searchDeviceByUdn(HUdn(uuid), AllDevices);
 
116
 
 
117
    if (!device)
 
118
    {
 
119
        HLOG_DBG(QString("No device with the specified UUID: [%1]").arg(
 
120
            uuid.toString()));
 
121
 
 
122
        return false;
 
123
    }
 
124
 
 
125
    QUrl location;
 
126
    if (!m_deviceStorage.searchValidLocation(device, source, &location))
 
127
    {
 
128
        HLOG_DBG(QString(
 
129
            "Found a device with uuid: [%1], but it is not "
 
130
            "available on the interface that has address: [%2]").arg(
 
131
                uuid.toString(), source.toString()));
 
132
 
 
133
        return false;
 
134
    }
 
135
 
 
136
    const HServerDeviceController* controller =
 
137
        m_deviceStorage.getController(device);
 
138
 
 
139
    Q_ASSERT(controller);
 
140
 
 
141
    responses->push_back(
 
142
        HDiscoveryResponse(
 
143
            controller->deviceTimeoutInSecs() * 2,
 
144
            QDateTime::currentDateTime(),
 
145
            location,
 
146
            HSysInfo::instance().herqqProductTokens(),
 
147
            st, // the searched usn
 
148
            device->deviceStatus().bootId(),
 
149
            device->deviceStatus().configId()
 
150
            ));
 
151
 
 
152
    return true;
 
153
}
 
154
 
 
155
bool HDeviceHostSsdpHandler::processSearchRequest_deviceType(
 
156
    const HDiscoveryRequest& req, const HEndpoint& source,
 
157
    QList<HDiscoveryResponse>* responses)
 
158
{
 
159
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
160
 
 
161
    HDiscoveryType st = req.searchTarget();
 
162
 
 
163
    QList<HServerDevice*> foundDevices =
 
164
        m_deviceStorage.searchDevicesByDeviceType(
 
165
            st.resourceType(),
 
166
            HResourceType::EqualOrGreater,
 
167
            AllDevices);
 
168
 
 
169
    if (!foundDevices.size())
 
170
    {
 
171
        HLOG_DBG(QString("No devices match the specified type: [%1]").arg(
 
172
            st.resourceType().toString()));
 
173
 
 
174
        return false;
 
175
    }
 
176
 
 
177
    qint32 prevSize = responses->size();
 
178
    foreach(const HServerDevice* device, foundDevices)
 
179
    {
 
180
        QUrl location;
 
181
        if (!m_deviceStorage.searchValidLocation(device, source, &location))
 
182
        {
 
183
            HLOG_DBG(QString(
 
184
                "Found a matching device, but it is not "
 
185
                "available on the interface that has address: [%1]").arg(
 
186
                    source.toString()));
 
187
 
 
188
            continue;
 
189
        }
 
190
 
 
191
        st.setUdn(device->info().udn());
 
192
 
 
193
        const HServerDeviceController* controller =
 
194
            m_deviceStorage.getController(device);
 
195
 
 
196
        Q_ASSERT(controller);
 
197
 
 
198
        responses->push_back(
 
199
            HDiscoveryResponse(
 
200
                controller->deviceTimeoutInSecs() * 2,
 
201
                QDateTime::currentDateTime(),
 
202
                location,
 
203
                HSysInfo::instance().herqqProductTokens(),
 
204
                st,
 
205
                device->deviceStatus().bootId(),
 
206
                device->deviceStatus().configId()
 
207
                ));
 
208
    }
 
209
 
 
210
    return responses->size() > prevSize;
 
211
}
 
212
 
 
213
bool HDeviceHostSsdpHandler::processSearchRequest_serviceType(
 
214
    const HDiscoveryRequest& req, const HEndpoint& source,
 
215
    QList<HDiscoveryResponse>* responses)
 
216
{
 
217
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
218
 
 
219
    HDiscoveryType st = req.searchTarget();
 
220
 
 
221
    QList<HServerService*> foundServices =
 
222
        m_deviceStorage.searchServicesByServiceType(
 
223
            st.resourceType(),
 
224
            HResourceType::EqualOrGreater);
 
225
 
 
226
    if (!foundServices.size())
 
227
    {
 
228
       HLOG_DBG(QString(
 
229
           "No services match the specified type: [%1]").arg(
 
230
               st.resourceType().toString()));
 
231
 
 
232
       return false;
 
233
    }
 
234
 
 
235
    qint32 prevSize = responses->size();
 
236
    foreach(const HServerService* service, foundServices)
 
237
    {
 
238
        const HServerDevice* device = service->parentDevice();
 
239
        Q_ASSERT(device);
 
240
 
 
241
        QUrl location;
 
242
        if (!m_deviceStorage.searchValidLocation(device, source, &location))
 
243
        {
 
244
            HLOG_DBG(QString(
 
245
                "Found a matching device, but it is not "
 
246
                "available on the interface that has address: [%1]").arg(
 
247
                    source.toString()));
 
248
 
 
249
            continue;
 
250
        }
 
251
 
 
252
        HDeviceInfo deviceInfo = device->info();
 
253
 
 
254
        const HServerDevice* dc =
 
255
            m_deviceStorage.searchDeviceByUdn(deviceInfo.udn(), AllDevices);
 
256
 
 
257
        Q_ASSERT(dc);
 
258
 
 
259
        st.setUdn(deviceInfo.udn());
 
260
 
 
261
        const HServerDeviceController* controller =
 
262
            m_deviceStorage.getController(device);
 
263
 
 
264
        Q_ASSERT(controller);
 
265
 
 
266
        responses->push_back(
 
267
            HDiscoveryResponse(
 
268
                controller->deviceTimeoutInSecs() * 2,
 
269
                QDateTime::currentDateTime(),
 
270
                location,
 
271
                HSysInfo::instance().herqqProductTokens(),
 
272
                st,
 
273
                dc->deviceStatus().bootId(),
 
274
                dc->deviceStatus().configId()
 
275
                ));
 
276
    }
 
277
 
 
278
    return responses->size() > prevSize;
 
279
}
 
280
 
 
281
void HDeviceHostSsdpHandler::processSearchRequest(
 
282
    const HServerDevice* device, const QUrl& location,
 
283
    QList<HDiscoveryResponse>* responses)
 
284
{
 
285
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
286
    Q_ASSERT(device);
 
287
 
 
288
    HDeviceInfo deviceInfo = device->info();
 
289
    HProductTokens pt = HSysInfo::instance().herqqProductTokens();
 
290
    HDiscoveryType usn(deviceInfo.udn());
 
291
 
 
292
    const HServerDeviceController* controller =
 
293
        m_deviceStorage.getController(device);
 
294
 
 
295
    Q_ASSERT(controller);
 
296
 
 
297
    const HDeviceStatus& deviceStatus = device->deviceStatus();
 
298
 
 
299
    // device UDN
 
300
    responses->push_back(
 
301
        HDiscoveryResponse(
 
302
            controller->deviceTimeoutInSecs() * 2,
 
303
            QDateTime::currentDateTime(), location, pt, usn,
 
304
            deviceStatus.bootId(),
 
305
            deviceStatus.configId()));
 
306
 
 
307
    usn.setResourceType(deviceInfo.deviceType());
 
308
 
 
309
    // device type
 
310
    responses->push_back(
 
311
        HDiscoveryResponse(
 
312
            controller->deviceTimeoutInSecs() * 2,
 
313
            QDateTime::currentDateTime(), location, pt, usn,
 
314
            deviceStatus.bootId(),
 
315
            deviceStatus.configId()));
 
316
 
 
317
    const HServerServices& services = device->services();
 
318
    foreach(const HServerService* service, services)
 
319
    {
 
320
        usn.setResourceType(service->info().serviceType());
 
321
 
 
322
        responses->push_back(
 
323
            HDiscoveryResponse(
 
324
                controller->deviceTimeoutInSecs() * 2,
 
325
                QDateTime::currentDateTime(), location, pt, usn,
 
326
                deviceStatus.bootId(),
 
327
                deviceStatus.configId()
 
328
                ));
 
329
    }
 
330
 
 
331
    const HServerDevices& devices = device->embeddedDevices();
 
332
    foreach(const HServerDevice* embeddedDevice, devices)
 
333
    {
 
334
        processSearchRequest(embeddedDevice, location, responses);
 
335
    }
 
336
}
 
337
 
 
338
bool HDeviceHostSsdpHandler::processSearchRequest_AllDevices(
 
339
    const HDiscoveryRequest& /*req*/, const HEndpoint& source,
 
340
    QList<HDiscoveryResponse>* responses)
 
341
{
 
342
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
343
    Q_ASSERT(responses);
 
344
 
 
345
    const HProductTokens& pt = HSysInfo::instance().herqqProductTokens();
 
346
 
 
347
    const HServerDevices& rootDevices = m_deviceStorage.rootDevices();
 
348
 
 
349
    qint32 prevSize = responses->size();
 
350
    foreach(const HServerDevice* rootDevice, rootDevices)
 
351
    {
 
352
        QUrl location;
 
353
        if (!m_deviceStorage.searchValidLocation(rootDevice, source, &location))
 
354
        {
 
355
            HLOG_DBG(QString(
 
356
                "Found a device, but it is not "
 
357
                "available on the interface that has address: [%1]").arg(
 
358
                    source.toString()));
 
359
 
 
360
            continue;
 
361
        }
 
362
 
 
363
        HDiscoveryType usn(rootDevice->info().udn(), true);
 
364
 
 
365
        const HServerDeviceController* controller =
 
366
            m_deviceStorage.getController(rootDevice);
 
367
 
 
368
        Q_ASSERT(controller);
 
369
 
 
370
        responses->push_back(
 
371
            HDiscoveryResponse(
 
372
                controller->deviceTimeoutInSecs() * 2,
 
373
                QDateTime::currentDateTime(),
 
374
                location,
 
375
                pt,
 
376
                usn,
 
377
                rootDevice->deviceStatus().bootId(),
 
378
                rootDevice->deviceStatus().configId()
 
379
                ));
 
380
 
 
381
        processSearchRequest(rootDevice, location, responses);
 
382
 
 
383
        const HServerDevices& devices = rootDevice->embeddedDevices();
 
384
        foreach(const HServerDevice* embeddedDevice, devices)
 
385
        {
 
386
            if (!m_deviceStorage.searchValidLocation(
 
387
                    embeddedDevice, source, &location))
 
388
            {
 
389
                // highly uncommon, but possible; the root device is "active"
 
390
                // on the network interface to which the request came,
 
391
                // but at least one of its embedded devices is not.
 
392
 
 
393
                HLOG_DBG(QString(
 
394
                    "Skipping an embedded device that is not "
 
395
                    "available on the interface that has address: [%1]").arg(
 
396
                        source.toString()));
 
397
 
 
398
                continue;
 
399
            }
 
400
 
 
401
            processSearchRequest(embeddedDevice, location, responses);
 
402
        }
 
403
    }
 
404
 
 
405
    return responses->size() > prevSize;
 
406
}
 
407
 
 
408
bool HDeviceHostSsdpHandler::processSearchRequest_RootDevice(
 
409
    const HDiscoveryRequest& /*req*/, const HEndpoint& source,
 
410
    QList<HDiscoveryResponse>* responses)
 
411
{
 
412
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
413
    Q_ASSERT(responses);
 
414
 
 
415
    const HServerDevices& rootDevices = m_deviceStorage.rootDevices();
 
416
 
 
417
    qint32 prevSize = responses->size();
 
418
    foreach(const HServerDevice* rootDevice, rootDevices)
 
419
    {
 
420
        QUrl location;
 
421
        if (!m_deviceStorage.searchValidLocation(rootDevice, source, &location))
 
422
        {
 
423
            HLOG_DBG(QString(
 
424
                "Found a root device, but it is not "
 
425
                "available on the interface that has address: [%1]").arg(
 
426
                    source.hostAddress().toString()));
 
427
 
 
428
            continue;
 
429
        }
 
430
 
 
431
        HDiscoveryType usn(rootDevice->info().udn(), true);
 
432
 
 
433
        const HServerDeviceController* controller =
 
434
            m_deviceStorage.getController(rootDevice);
 
435
 
 
436
        Q_ASSERT(controller);
 
437
 
 
438
        responses->push_back(
 
439
            HDiscoveryResponse(
 
440
                controller->deviceTimeoutInSecs() * 2,
 
441
                QDateTime::currentDateTime(),
 
442
                location,
 
443
                HSysInfo::instance().herqqProductTokens(),
 
444
                usn,
 
445
                rootDevice->deviceStatus().bootId(),
 
446
                rootDevice->deviceStatus().configId()));
 
447
    }
 
448
 
 
449
    return responses->size() > prevSize;
 
450
}
 
451
 
 
452
bool HDeviceHostSsdpHandler::incomingDiscoveryRequest(
 
453
    const HDiscoveryRequest& msg, const HEndpoint& source,
 
454
    DiscoveryRequestMethod requestType)
 
455
{
 
456
    HLOG2(H_AT, H_FUN, h_ptr->m_loggingIdentifier);
 
457
 
 
458
    HLOG_DBG(QString("Received discovery request for [%1] from [%2]").arg(
 
459
        msg.searchTarget().toString(), source.toString()));
 
460
 
 
461
    bool ok = false;
 
462
    QList<HDiscoveryResponse> responses;
 
463
    switch (msg.searchTarget().type())
 
464
    {
 
465
        case HDiscoveryType::All:
 
466
            ok = processSearchRequest_AllDevices(msg, source, &responses);
 
467
            break;
 
468
 
 
469
        case HDiscoveryType::RootDevices:
 
470
            ok = processSearchRequest_RootDevice(msg, source, &responses);
 
471
            break;
 
472
 
 
473
        case HDiscoveryType::SpecificDevice:
 
474
            ok = processSearchRequest_specificDevice(msg, source, &responses);
 
475
            break;
 
476
 
 
477
        case HDiscoveryType::DeviceType:
 
478
            ok = processSearchRequest_deviceType(msg, source, &responses);
 
479
            break;
 
480
 
 
481
        case HDiscoveryType::ServiceType:
 
482
            ok = processSearchRequest_serviceType(msg, source, &responses);
 
483
            break;
 
484
 
 
485
        default:
 
486
            return true;
 
487
    }
 
488
 
 
489
    if (ok)
 
490
    {
 
491
        if (requestType == MulticastDiscovery)
 
492
        {
 
493
            HDelayedWriter* writer =
 
494
                new HDelayedWriter(
 
495
                    *this, responses, source, (qrand() % msg.mx()) * 1000);
 
496
 
 
497
            bool ok =
 
498
                connect(writer, SIGNAL(sent()), writer, SLOT(deleteLater()));
 
499
 
 
500
            Q_ASSERT(ok); Q_UNUSED(ok)
 
501
 
 
502
            writer->run();
 
503
        }
 
504
        else
 
505
        {
 
506
            foreach (const HDiscoveryResponse& resp, responses)
 
507
            {
 
508
                qint32 count = sendDiscoveryResponse(resp, source);
 
509
                Q_ASSERT(count >= 0); Q_UNUSED(count)
 
510
            }
 
511
        }
 
512
    }
 
513
    else
 
514
    {
 
515
        HLOG_DBG(QString(
 
516
            "No resources found for discovery request [%1] from [%2]").arg(
 
517
                msg.searchTarget().toString(), source.toString()));
 
518
    }
 
519
 
 
520
    return true;
 
521
}
 
522
 
 
523
}
 
524
}