Switch to unified view

a/upmpd/upmpd.cxx b/upmpd/upmpd.cxx
...
...
77
        }
77
        }
78
}
78
}
79
79
80
// Note: if we ever need this to work without cxx11, there is this:
80
// Note: if we ever need this to work without cxx11, there is this:
81
// http://www.tutok.sk/fastgl/callback.html
81
// http://www.tutok.sk/fastgl/callback.html
82
//
83
// Note that there is a problem in the order in which we do things
84
// here: because the UpnpDevice() constructor starts the
85
// advertisements and publishes the description document before the
86
// services are actually initialized, it is possible that a fast
87
// client will fail in subscribing to events, which will manifest
88
// itself on the server side by error messages like the following in
89
// the log:
90
//   libupnpp/device/device.cxx:183::UpnpDevice: Bad serviceID: 
91
//        urn:upnp-org:serviceId:ConnectionManager
92
// The solution would be to have a separate init call to start the
93
// device at the end of the constructor code.
82
UpMpd::UpMpd(const string& deviceid, const string& friendlyname,
94
UpMpd::UpMpd(const string& deviceid, const string& friendlyname,
83
             const unordered_map<string, string>& xmlfiles,
95
             const unordered_map<string, VDirContent>& files,
84
             MPDCli *mpdcli, unsigned int opts, const string& cachefn)
96
             MPDCli *mpdcli, unsigned int opts, const string& cachefn)
85
    : UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_mpds(0),
97
    : UpnpDevice(deviceid, files), m_mpdcli(mpdcli), m_mpds(0),
86
      m_options(opts),
98
      m_options(opts),
87
      m_mcachefn(cachefn)
99
      m_mcachefn(cachefn)
88
{
100
{
89
    // Note: the order is significant here as it will be used when
101
    // Note: the order is significant here as it will be used when
90
    // calling the getStatus() methods, and we want AVTransport to
102
    // calling the getStatus() methods, and we want AVTransport to
...
...
159
    "  <serviceId>urn:av-openhome-org:serviceId:Playlist</serviceId>"
171
    "  <serviceId>urn:av-openhome-org:serviceId:Playlist</serviceId>"
160
    "  <SCPDURL>/OHPlaylist.xml</SCPDURL>"
172
    "  <SCPDURL>/OHPlaylist.xml</SCPDURL>"
161
    "  <controlURL>/ctl/OHPlaylist</controlURL>"
173
    "  <controlURL>/ctl/OHPlaylist</controlURL>"
162
    "  <eventSubURL>/evt/OHPlaylist</eventSubURL>"
174
    "  <eventSubURL>/evt/OHPlaylist</eventSubURL>"
163
    "</service>"
175
    "</service>"
176
    );
177
178
static const string iconDesc(
179
    "<iconList>"
180
    "  <icon>"
181
    "    <mimetype>image/png</mimetype>"
182
    "    <width>64</width>"
183
    "    <height>64</height>"
184
    "    <depth>32</depth>"
185
    "    <url>/icon.png</url>"
186
    "  </icon>"
187
    "</iconList>"
164
    );
188
    );
165
189
166
static char *thisprog;
190
static char *thisprog;
167
191
168
static int op_flags;
192
static int op_flags;
...
...
292
    }
316
    }
293
317
294
    if (argc != 0)
318
    if (argc != 0)
295
        Usage();
319
        Usage();
296
320
321
    string iconpath;
297
    if (!configfile.empty()) {
322
    if (!configfile.empty()) {
298
        ConfSimple config(configfile.c_str(), 1, true);
323
        ConfSimple config(configfile.c_str(), 1, true);
299
        if (!config.ok()) {
324
        if (!config.ok()) {
300
            cerr << "Could not open config: " << configfile << endl;
325
            cerr << "Could not open config: " << configfile << endl;
301
            return 1;
326
            return 1;
...
...
320
            openhome = atoi(value.c_str()) != 0;
345
            openhome = atoi(value.c_str()) != 0;
321
        }
346
        }
322
        if (config.get("ohmetapersist", value)) {
347
        if (config.get("ohmetapersist", value)) {
323
            ohmetapersist = atoi(value.c_str()) != 0;
348
            ohmetapersist = atoi(value.c_str()) != 0;
324
        }
349
        }
350
        config.get("iconpath", iconpath);
325
        if (!(op_flags & OPT_i)) {
351
        if (!(op_flags & OPT_i)) {
326
            config.get("upnpiface", iface);
352
            config.get("upnpiface", iface);
327
            if (iface.empty()) {
353
            if (iface.empty()) {
328
                config.get("upnpip", upnpip);
354
                config.get("upnpip", upnpip);
329
            }
355
            }
...
...
470
        if (!read_protocolinfo(protofile, upmpdProtocolInfo)) {
496
        if (!read_protocolinfo(protofile, upmpdProtocolInfo)) {
471
            LOGFAT("Failed reading protocol info from " << protofile << endl);
497
            LOGFAT("Failed reading protocol info from " << protofile << endl);
472
            return 1;
498
            return 1;
473
        }
499
        }
474
    }
500
    }
475
            
501
476
    string reason;
502
    string reason;
503
504
    string icondata;
505
    if (!iconpath.empty()) {
506
        if (!file_to_string(iconpath, icondata, &reason)) {
507
            LOGERR("Failed reading " << iconpath << " : " << reason << endl);
508
        }
509
    }
510
477
    unordered_map<string, string> xmlfiles;
511
    unordered_map<string, VDirContent> files;
478
    for (unsigned int i = 0; i < xmlfilenames.size(); i++) {
512
    for (unsigned int i = 0; i < xmlfilenames.size(); i++) {
479
        string filename = path_cat(datadir, xmlfilenames[i]);
513
        string filename = path_cat(datadir, xmlfilenames[i]);
480
        string data;
514
        string data;
481
        if (!file_to_string(filename, data, &reason)) {
515
        if (!file_to_string(filename, data, &reason)) {
482
            LOGFAT("Failed reading " << filename << " : " << reason << endl);
516
            LOGFAT("Failed reading " << filename << " : " << reason << endl);
...
...
486
            // Special for description: set UUID and friendlyname
520
            // Special for description: set UUID and friendlyname
487
            data = regsub1("@UUID@", data, UUID);
521
            data = regsub1("@UUID@", data, UUID);
488
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
522
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
489
            if (openhome) 
523
            if (openhome) 
490
                data = regsub1("@OPENHOME@", data, ohDesc);
524
                data = regsub1("@OPENHOME@", data, ohDesc);
491
        }
525
            else 
492
        xmlfiles[xmlfilenames[i]] = data;
526
                data = regsub1("@OPENHOME@", data, "");
527
            if (!icondata.empty())
528
                data = regsub1("@ICONLIST@", data, iconDesc);
529
            else
530
                data = regsub1("@ICONLIST@", data, "");
493
    }
531
        }
532
        files.insert(pair<string, VDirContent>
533
                     (xmlfilenames[i], VDirContent(data, "application/xml")));
534
    }
535
536
    if (!icondata.empty()) {
537
        files.insert(pair<string, VDirContent>
538
                     ("icon.png", VDirContent(icondata, "image/png")));
539
    }
540
494
    unsigned int options = UpMpd::upmpdNone;
541
    unsigned int options = UpMpd::upmpdNone;
495
    if (ownqueue)
542
    if (ownqueue)
496
        options |= UpMpd::upmpdOwnQueue;
543
        options |= UpMpd::upmpdOwnQueue;
497
    if (openhome)
544
    if (openhome)
498
        options |= UpMpd::upmpdDoOH;
545
        options |= UpMpd::upmpdDoOH;
499
    if (ohmetapersist)
546
    if (ohmetapersist)
500
        options |= UpMpd::upmpdOhMetaPersist;
547
        options |= UpMpd::upmpdOhMetaPersist;
501
548
502
    // Initialize the UPnP device object.
549
    // Initialize the UPnP device object.
503
    UpMpd device(string("uuid:") + UUID, friendlyname, 
550
    UpMpd device(string("uuid:") + UUID, friendlyname, 
504
                 xmlfiles, mpdclip, options, mcfn);
551
                 files, mpdclip, options, mcfn);
505
    dev = &device;
552
    dev = &device;
506
553
507
    // And forever generate state change events.
554
    // And forever generate state change events.
508
    LOGDEB("Entering event loop" << endl);
555
    LOGDEB("Entering event loop" << endl);
509
    setupsigs();
556
    setupsigs();