Switch to unified view

a/upmpd/upmpd.cxx b/upmpd/upmpd.cxx
...
...
51
51
52
// Note: if we ever need this to work without cxx11, there is this:
52
// Note: if we ever need this to work without cxx11, there is this:
53
// http://www.tutok.sk/fastgl/callback.html
53
// http://www.tutok.sk/fastgl/callback.html
54
UpMpd::UpMpd(const string& deviceid, 
54
UpMpd::UpMpd(const string& deviceid, 
55
             const unordered_map<string, string>& xmlfiles,
55
             const unordered_map<string, string>& xmlfiles,
56
             MPDCli *mpdcli, Options opts)
56
             MPDCli *mpdcli, unsigned int opts)
57
    : UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_mpds(0),
57
    : UpnpDevice(deviceid, xmlfiles), m_mpdcli(mpdcli), m_mpds(0),
58
      m_options(opts)
58
      m_options(opts)
59
{
59
{
60
    // Note: the order is significant here as it will be used when
60
    // Note: the order is significant here as it will be used when
61
    // calling the getStatus() methods, and we want AVTransport to
61
    // calling the getStatus() methods, and we want AVTransport to
62
    // update the mpd status for OHInfo
62
    // update the mpd status for OHInfo
63
    UpMpdRenderCtl *rdctl = new UpMpdRenderCtl(this);
63
    UpMpdRenderCtl *rdctl = new UpMpdRenderCtl(this);
64
    m_services.push_back(rdctl);
64
    m_services.push_back(rdctl);
65
    m_services.push_back(new UpMpdAVTransport(this));
65
    m_services.push_back(new UpMpdAVTransport(this));
66
    m_services.push_back(new UpMpdConMan(this));
66
    m_services.push_back(new UpMpdConMan(this));
67
  if (m_options & upmpdDoOH) {
67
    m_services.push_back(new OHProduct(this));
68
     m_services.push_back(new OHProduct(this));
68
    m_services.push_back(new OHInfo(this));
69
     m_services.push_back(new OHInfo(this));
69
    m_services.push_back(new OHTime(this));
70
     m_services.push_back(new OHTime(this));
70
    m_services.push_back(new OHVolume(this, rdctl));
71
     m_services.push_back(new OHVolume(this, rdctl));
71
    m_services.push_back(new OHPlaylist(this, rdctl));
72
     m_services.push_back(new OHPlaylist(this, rdctl));
73
  }
72
}
74
}
73
75
74
UpMpd::~UpMpd()
76
UpMpd::~UpMpd()
75
{
77
{
76
    for (vector<UpnpService*>::iterator it = m_services.begin();
78
    for (vector<UpnpService*>::iterator it = m_services.begin();
...
...
105
#define OPT_i     0x200
107
#define OPT_i     0x200
106
#define OPT_P     0x400
108
#define OPT_P     0x400
107
109
108
static const char usage[] = 
110
static const char usage[] = 
109
"-c configfile \t configuration file to use\n"
111
"-c configfile \t configuration file to use\n"
110
"-h host    \t specify host MPD is running on\n"
112
"""""""""""""""""""""""""""""-h host    \t specify host MPD is running on\n"""""""""""""""""""""""""""""
111
"-p port     \t specify MPD port\n"
113
"-p port     \t specify MPD port\n"
112
"-d logfilename\t debug messages to\n"
114
"-d logfilename\t debug messages to\n"
113
"-l loglevel\t  log level (0-6)\n"
115
"-l loglevel\t  log level (0-6)\n"
114
"-D          \t run as a daemon\n"
116
"-D    \t run as a daemon\n"
115
"-f friendlyname\t define device displayed name\n"
117
"-f friendlyname\t define device displayed name\n"
116
"-q 0|1      \t if set, we own the mpd queue, else avoid clearing it whenever we feel like it\n"
118
"-q 0|1\t if set, we own the mpd queue, else avoid clearing it whenever we feel like it\n"
117
"-i iface    \t specify network interface name to be used for UPnP"
119
"-i iface    \t specify network interface name to be used for UPnP"
118
"-P upport    \t specify port number to be used for UPnP"
120
"-P upport    \t specify port number to be used for UPnP"
119
"  \n\n"
121
"  \n\n"
120
            ;
122
            ;
121
static void
123
static void
...
...
129
131
130
static string datadir(DATADIR "/");
132
static string datadir(DATADIR "/");
131
static string configdir(CONFIGDIR "/");
133
static string configdir(CONFIGDIR "/");
132
134
133
// Our XML description data. !Keep description.xml first!
135
// Our XML description data. !Keep description.xml first!
134
static const char *xmlfilenames[] = 
136
static vector<const char *> xmlfilenames = 
137
{
135
{/* keep first */ "description.xml", 
138
  /* keep first */ "description.xml", /* keep first */
136
 "RenderingControl.xml", "AVTransport.xml", "ConnectionManager.xml",
139
  "RenderingControl.xml", "AVTransport.xml", "ConnectionManager.xml",
137
 "OHProduct.xml", "OHInfo.xml", "OHTime.xml", "OHVolume.xml", 
138
 "OHPlaylist.xml",
139
};
140
};
141
static vector<const char *> ohxmlfilenames = 
142
{
143
  "OHProduct.xml", "OHInfo.xml", "OHTime.xml", "OHVolume.xml", 
144
  "OHPlaylist.xml",
145
};
140
146
141
static const int xmlfilenamescnt = sizeof(xmlfilenames) / sizeof(char *);
147
148
static const string ohDesc(
149
  "<service>"
150
  "  <serviceType>urn:av-openhome-org:service:Product:1</serviceType>"
151
  "  <serviceId>urn:av-openhome-org:serviceId:Product</serviceId>"
152
  "  <SCPDURL>/OHProduct.xml</SCPDURL>"
153
  "  <controlURL>/ctl/OHProduct</controlURL>"
154
  "  <eventSubURL>/evt/OHProduct</eventSubURL>"
155
  "</service>"
156
  "<service>"
157
  "  <serviceType>urn:av-openhome-org:service:Info:1</serviceType>"
158
  "  <serviceId>urn:av-openhome-org:serviceId:Info</serviceId>"
159
  "  <SCPDURL>/OHInfo.xml</SCPDURL>"
160
  "  <controlURL>/ctl/OHInfo</controlURL>"
161
  "  <eventSubURL>/evt/OHInfo</eventSubURL>"
162
  "</service>"
163
  "<service>"
164
  "  <serviceType>urn:av-openhome-org:service:Time:1</serviceType>"
165
  "  <serviceId>urn:av-openhome-org:serviceId:Time</serviceId>"
166
  "  <SCPDURL>/OHTime.xml</SCPDURL>"
167
  "  <controlURL>/ctl/OHTime</controlURL>"
168
  "  <eventSubURL>/evt/OHTime</eventSubURL>"
169
  "</service>"
170
  "<service>"
171
  "  <serviceType>urn:av-openhome-org:service:Volume:1</serviceType>"
172
  "  <serviceId>urn:av-openhome-org:serviceId:Volume</serviceId>"
173
  "  <SCPDURL>/OHVolume.xml</SCPDURL>"
174
  "  <controlURL>/ctl/OHVolume</controlURL>"
175
  "  <eventSubURL>/evt/OHVolume</eventSubURL>"
176
  "</service>"
177
  "<service>"
178
  "  <serviceType>urn:av-openhome-org:service:Playlist:1</serviceType>"
179
  "  <serviceId>urn:av-openhome-org:serviceId:Playlist</serviceId>"
180
  "  <SCPDURL>/OHPlaylist.xml</SCPDURL>"
181
  "  <controlURL>/ctl/OHPlaylist</controlURL>"
182
  "  <eventSubURL>/evt/OHPlaylist</eventSubURL>"
183
  "</service>"
184
  );
142
185
143
int main(int argc, char *argv[])
186
int main(int argc, char *argv[])
144
{
187
{
145
    string mpdhost("localhost");
188
    string mpdhost("localhost");
146
    int mpdport = 6600;
189
    int mpdport = 6600;
...
...
148
    string logfilename;
191
    string logfilename;
149
    int loglevel(upnppdebug::Logger::LLINF);
192
    int loglevel(upnppdebug::Logger::LLINF);
150
    string configfile;
193
    string configfile;
151
    string friendlyname(dfltFriendlyName);
194
    string friendlyname(dfltFriendlyName);
152
    bool ownqueue = true;
195
    bool ownqueue = true;
196
  bool openhome = false;
153
    string upmpdcliuser("upmpdcli");
197
    string upmpdcliuser("upmpdcli");
154
    string pidfilename("/var/run/upmpdcli.pid");
198
    string pidfilename("/var/run/upmpdcli.pid");
155
    string iface;
199
    string iface;
156
    unsigned short upport = 0;
200
    unsigned short upport = 0;
157
    string upnpip;
201
    string upnpip;
...
...
225
        }
269
        }
226
        config.get("mpdpassword", mpdpassword);
270
        config.get("mpdpassword", mpdpassword);
227
        if (!(op_flags & OPT_q) && config.get("ownqueue", value)) {
271
        if (!(op_flags & OPT_q) && config.get("ownqueue", value)) {
228
            ownqueue = atoi(value.c_str()) != 0;
272
            ownqueue = atoi(value.c_str()) != 0;
229
        }
273
        }
274
      if (config.get("openhome", value)) {
275
          openhome = atoi(value.c_str()) != 0;
276
      }
230
        if (!(op_flags & OPT_i)) {
277
        if (!(op_flags & OPT_i)) {
231
            config.get("upnpiface", iface);
278
            config.get("upnpiface", iface);
232
            if (iface.empty()) {
279
            if (iface.empty()) {
233
                config.get("upnpip", upnpip);
280
                config.get("upnpip", upnpip);
234
            }
281
            }
...
...
324
371
325
    // Create unique ID
372
    // Create unique ID
326
    string UUID = LibUPnP::makeDevUUID(friendlyname, hwaddr);
373
    string UUID = LibUPnP::makeDevUUID(friendlyname, hwaddr);
327
374
328
    // Read our XML data to make it available from the virtual directory
375
    // Read our XML data to make it available from the virtual directory
376
  if (openhome) {
377
      xmlfilenames.insert(xmlfilenames.end(), ohxmlfilenames.begin(),
378
                          ohxmlfilenames.end());
379
  }
329
    string reason;
380
    string reason;
330
    unordered_map<string, string> xmlfiles;
381
    unordered_map<string, string> xmlfiles;
331
    for (int i = 0; i < xmlfilenamescnt; i++) {
382
    for (unsigned int i = 0; i < xmlfilenames.size(); i++) {
332
        string filename = path_cat(datadir, xmlfilenames[i]);
383
        string filename = path_cat(datadir, xmlfilenames[i]);
333
        string data;
384
        string data;
334
        if (!file_to_string(filename, data, &reason)) {
385
        if (!file_to_string(filename, data, &reason)) {
335
            LOGFAT("Failed reading " << filename << " : " << reason << endl);
386
            LOGFAT("Failed reading " << filename << " : " << reason << endl);
336
            return 1;
387
            return 1;
337
        }
388
        }
338
        if (i == 0) {
389
        if (i == 0) {
339
            // Special for description: set UUID and friendlyname
390
            // Special for description: set UUID and friendlyname
340
            data = regsub1("@UUID@", data, UUID);
391
            data = regsub1("@UUID@", data, UUID);
341
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
392
            data = regsub1("@FRIENDLYNAME@", data, friendlyname);
393
          if (openhome) 
394
              data = regsub1("@OPENHOME@", data, ohDesc);
342
        }
395
        }
343
        xmlfiles[xmlfilenames[i]] = data;
396
        xmlfiles[xmlfilenames[i]] = data;
344
    }
397
    }
345
398
  unsigned int options = UpMpd::upmpdNone;
399
  if (ownqueue)
400
      options |= UpMpd::upmpdOwnQueue;
401
  if (openhome)
402
      options |= UpMpd::upmpdDoOH;
346
    // Initialize the UPnP device object.
403
    // Initialize the UPnP device object.
347
    UpMpd device(string("uuid:") + UUID, xmlfiles, &mpdcli,
404
    UpMpd device(string("uuid:") + UUID, xmlfiles, &mpdcli, options);
348
               ownqueue ? UpMpd::upmpdOwnQueue : UpMpd::upmpdNone);
349
405
350
    // And forever generate state change events.
406
    // And forever generate state change events.
351
    LOGDEB("Entering event loop" << endl);
407
    LOGDEB("Entering event loop" << endl);
352
    device.eventloop();
408
    device.eventloop();
353
409