Switch to unified view

a/src/upmpd.cxx b/src/upmpd.cxx
...
...
39
#include "conman.hxx"                   // for UpMpdConMan
39
#include "conman.hxx"                   // for UpMpdConMan
40
#include "mpdcli.hxx"                   // for MPDCli
40
#include "mpdcli.hxx"                   // for MPDCli
41
#include "ohinfo.hxx"                   // for OHInfo
41
#include "ohinfo.hxx"                   // for OHInfo
42
#include "ohplaylist.hxx"               // for OHPlaylist
42
#include "ohplaylist.hxx"               // for OHPlaylist
43
#include "ohproduct.hxx"                // for OHProduct
43
#include "ohproduct.hxx"                // for OHProduct
44
#include "ohreceiver.hxx"
44
#include "ohtime.hxx"                   // for OHTime
45
#include "ohtime.hxx"                   // for OHTime
45
#include "ohvolume.hxx"                 // for OHVolume
46
#include "ohvolume.hxx"                 // for OHVolume
46
#include "renderctl.hxx"                // for UpMpdRenderCtl
47
#include "renderctl.hxx"                // for UpMpdRenderCtl
47
#include "upmpdutils.hxx"               // for path_cat, Pidfile, regsub1, etc
48
#include "upmpdutils.hxx"               // for path_cat, Pidfile, regsub1, etc
49
#include "execmd.h"
48
50
49
using namespace std;
51
using namespace std;
50
using namespace std::placeholders;
52
using namespace std::placeholders;
51
using namespace UPnPP;
53
using namespace UPnPP;
52
54
53
static const string dfltFriendlyName("UpMpd");
55
static const string dfltFriendlyName("UpMpd");
54
string upmpdProtocolInfo;
56
string upmpdProtocolInfo;
57
58
// Is scmpdcli (songcast-to-HTTP command) installed ? We only create
59
// an OpenHome Receiver service if it is. This is checked when
60
// starting up
61
static bool has_scmpdcli(false);
55
62
56
static UpnpDevice *dev;
63
static UpnpDevice *dev;
57
64
58
static void onsig(int)
65
static void onsig(int)
59
{
66
{
...
...
91
//        urn:upnp-org:serviceId:ConnectionManager
98
//        urn:upnp-org:serviceId:ConnectionManager
92
// The solution would be to have a separate init call to start the
99
// The solution would be to have a separate init call to start the
93
// device at the end of the constructor code.
100
// device at the end of the constructor code.
94
UpMpd::UpMpd(const string& deviceid, const string& friendlyname,
101
UpMpd::UpMpd(const string& deviceid, const string& friendlyname,
95
             const unordered_map<string, VDirContent>& files,
102
             const unordered_map<string, VDirContent>& files,
96
             MPDCli *mpdcli, unsigned int opts, const string& cachefn)
103
             MPDCli *mpdcli, unsigned int opts, const string& cachefn,
104
             int schttpport
105
    )
97
    : UpnpDevice(deviceid, files), m_mpdcli(mpdcli), m_mpds(0),
106
    : UpnpDevice(deviceid, files), m_mpdcli(mpdcli), m_mpds(0),
98
      m_options(opts),
107
      m_options(opts),
99
      m_mcachefn(cachefn)
108
      m_mcachefn(cachefn)
100
{
109
{
101
    // Note: the order is significant here as it will be used when
110
    // Note: the order is significant here as it will be used when
...
...
105
    m_services.push_back(rdctl);
114
    m_services.push_back(rdctl);
106
    UpMpdAVTransport* avt = new UpMpdAVTransport(this);
115
    UpMpdAVTransport* avt = new UpMpdAVTransport(this);
107
    m_services.push_back(avt);
116
    m_services.push_back(avt);
108
    m_services.push_back(new UpMpdConMan(this));
117
    m_services.push_back(new UpMpdConMan(this));
109
    if (m_options & upmpdDoOH) {
118
    if (m_options & upmpdDoOH) {
110
        m_services.push_back(new OHProduct(this, friendlyname));
119
        m_services.push_back(new OHProduct(this, friendlyname, has_scmpdcli));
111
        m_services.push_back(new OHInfo(this));
120
        m_services.push_back(new OHInfo(this));
112
        m_services.push_back(new OHTime(this));
121
        m_services.push_back(new OHTime(this));
113
        m_services.push_back(new OHVolume(this, rdctl));
122
        m_services.push_back(new OHVolume(this, rdctl));
114
        OHPlaylist *ohp = new OHPlaylist(this, rdctl);
123
        OHPlaylist *ohp = new OHPlaylist(this, rdctl);
115
        m_services.push_back(ohp);
124
        m_services.push_back(ohp);
116
        if (avt)
125
        if (avt)
117
            avt->setOHP(ohp);
126
            avt->setOHP(ohp);
127
        if (has_scmpdcli) {
128
            m_services.push_back(new OHReceiver(this, ohp, schttpport));
129
        }
118
    }
130
    }
119
}
131
}
120
132
121
UpMpd::~UpMpd()
133
UpMpd::~UpMpd()
122
{
134
{
...
...
135
/////////////////////////////////////////////////////////////////////
147
/////////////////////////////////////////////////////////////////////
136
// Main program
148
// Main program
137
149
138
#include "conftree.hxx"
150
#include "conftree.hxx"
139
151
140
static const string ohDesc(
152
static string ohDesc(
141
    "<service>"
153
    "<service>"
142
    "  <serviceType>urn:av-openhome-org:service:Product:1</serviceType>"
154
    "  <serviceType>urn:av-openhome-org:service:Product:1</serviceType>"
143
    "  <serviceId>urn:av-openhome-org:serviceId:Product</serviceId>"
155
    "  <serviceId>urn:av-openhome-org:serviceId:Product</serviceId>"
144
    "  <SCPDURL>/OHProduct.xml</SCPDURL>"
156
    "  <SCPDURL>/OHProduct.xml</SCPDURL>"
145
    "  <controlURL>/ctl/OHProduct</controlURL>"
157
    "  <controlURL>/ctl/OHProduct</controlURL>"
...
...
170
    "  <serviceType>urn:av-openhome-org:service:Playlist:1</serviceType>"
182
    "  <serviceType>urn:av-openhome-org:service:Playlist:1</serviceType>"
171
    "  <serviceId>urn:av-openhome-org:serviceId:Playlist</serviceId>"
183
    "  <serviceId>urn:av-openhome-org:serviceId:Playlist</serviceId>"
172
    "  <SCPDURL>/OHPlaylist.xml</SCPDURL>"
184
    "  <SCPDURL>/OHPlaylist.xml</SCPDURL>"
173
    "  <controlURL>/ctl/OHPlaylist</controlURL>"
185
    "  <controlURL>/ctl/OHPlaylist</controlURL>"
174
    "  <eventSubURL>/evt/OHPlaylist</eventSubURL>"
186
    "  <eventSubURL>/evt/OHPlaylist</eventSubURL>"
187
    "</service>"
188
    );
189
static string ohDescReceive(
190
    "<service>"
191
    "  <serviceType>urn:av-openhome-org:service:Receiver:1</serviceType>"
192
    "  <serviceId>urn:av-openhome-org:serviceId:Receiver</serviceId>"
193
    "  <SCPDURL>/OHReceiver.xml</SCPDURL>"
194
    "  <controlURL>/ctl/OHReceiver</controlURL>"
195
    "  <eventSubURL>/evt/OHReceiver</eventSubURL>"
175
    "</service>"
196
    "</service>"
176
    );
197
    );
177
198
178
static const string iconDesc(
199
static const string iconDesc(
179
    "<iconList>"
200
    "<iconList>"
...
...
316
    }
337
    }
317
338
318
    if (argc != 0)
339
    if (argc != 0)
319
        Usage();
340
        Usage();
320
341
342
    int schttpport(8888);
321
    string iconpath;
343
    string iconpath;
322
    if (!configfile.empty()) {
344
    if (!configfile.empty()) {
323
        ConfSimple config(configfile.c_str(), 1, true);
345
        ConfSimple config(configfile.c_str(), 1, true);
324
        if (!config.ok()) {
346
        if (!config.ok()) {
325
            cerr << "Could not open config: " << configfile << endl;
347
            cerr << "Could not open config: " << configfile << endl;
...
...
355
            }
377
            }
356
        }
378
        }
357
        if (!(op_flags & OPT_P) && config.get("upnpport", value)) {
379
        if (!(op_flags & OPT_P) && config.get("upnpport", value)) {
358
            upport = atoi(value.c_str());
380
            upport = atoi(value.c_str());
359
        }
381
        }
382
        if (config.get("schttpport", value))
383
            schttpport = atoi(value.c_str());
360
    }
384
    }
361
385
362
    if (Logger::getTheLog(logfilename) == 0) {
386
    if (Logger::getTheLog(logfilename) == 0) {
363
        cerr << "Can't initialize log" << endl;
387
        cerr << "Can't initialize log" << endl;
364
        return 1;
388
        return 1;
...
...
456
        } else {
480
        } else {
457
            break;
481
            break;
458
        }
482
        }
459
    }
483
    }
460
484
485
    // Do we have an scmpdcli command installed (for songcast)?
486
    string unused;
487
    has_scmpdcli = ExecCmd::which("scmpdcli", unused);
488
461
    // Initialize libupnpp, and check health
489
    // Initialize libupnpp, and check health
462
    LibUPnP *mylib = 0;
490
    LibUPnP *mylib = 0;
463
    string hwaddr;
491
    string hwaddr;
464
    int libretrysecs = 10;
492
    int libretrysecs = 10;
465
    for (;;) {
493
    for (;;) {
...
...
497
    // Create unique ID
525
    // Create unique ID
498
    string UUID = LibUPnP::makeDevUUID(friendlyname, hwaddr);
526
    string UUID = LibUPnP::makeDevUUID(friendlyname, hwaddr);
499
527
500
    // Read our XML data to make it available from the virtual directory
528
    // Read our XML data to make it available from the virtual directory
501
    if (openhome) {
529
    if (openhome) {
530
        if (has_scmpdcli) {
531
            ohxmlfilenames.push_back("OHReceiver.xml");
532
        }
502
        xmlfilenames.insert(xmlfilenames.end(), ohxmlfilenames.begin(),
533
        xmlfilenames.insert(xmlfilenames.end(), ohxmlfilenames.begin(),
503
                            ohxmlfilenames.end());
534
                            ohxmlfilenames.end());
504
    }
535
    }
505
536
506
    {
537
    {
...
...
530
        }
561
        }
531
        if (i == 0) {
562
        if (i == 0) {
532
            // Special for description: set UUID and friendlyname
563
            // Special for description: set UUID and friendlyname
533
            data = regsub1("@UUID@", data, UUID);
564
            data = regsub1("@UUID@", data, UUID);
534
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
565
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
535
            if (openhome) 
566
            if (openhome) {
567
                if (has_scmpdcli) {
568
                    ohDesc += ohDescReceive;
569
                }
536
                data = regsub1("@OPENHOME@", data, ohDesc);
570
                data = regsub1("@OPENHOME@", data, ohDesc);
537
            else 
571
            } else {
538
                data = regsub1("@OPENHOME@", data, "");
572
                data = regsub1("@OPENHOME@", data, "");
573
            }
539
            if (!icondata.empty())
574
            if (!icondata.empty())
540
                data = regsub1("@ICONLIST@", data, iconDesc);
575
                data = regsub1("@ICONLIST@", data, iconDesc);
541
            else
576
            else
542
                data = regsub1("@ICONLIST@", data, "");
577
                data = regsub1("@ICONLIST@", data, "");
543
        }
578
        }
...
...
558
    if (ohmetapersist)
593
    if (ohmetapersist)
559
        options |= UpMpd::upmpdOhMetaPersist;
594
        options |= UpMpd::upmpdOhMetaPersist;
560
595
561
    // Initialize the UPnP device object.
596
    // Initialize the UPnP device object.
562
    UpMpd device(string("uuid:") + UUID, friendlyname, 
597
    UpMpd device(string("uuid:") + UUID, friendlyname, 
563
                 files, mpdclip, options, mcfn);
598
                 files, mpdclip, options, mcfn, schttpport);
564
    dev = &device;
599
    dev = &device;
565
600
566
    // And forever generate state change events.
601
    // And forever generate state change events.
567
    LOGDEB("Entering event loop" << endl);
602
    LOGDEB("Entering event loop" << endl);
568
    setupsigs();
603
    setupsigs();