--- a/src/upmpd.cxx
+++ b/src/upmpd.cxx
@@ -51,38 +51,6 @@
using namespace std;
using namespace std::placeholders;
using namespace UPnPP;
-
-static const string dfltFriendlyName("UpMpd");
-string upmpdProtocolInfo;
-
-// Is sc2mpd (songcast-to-HTTP command) installed ? We only create
-// an OpenHome Receiver service if it is. This is checked when
-// starting up
-static bool has_sc2mpd(false);
-
-static UpnpDevice *dev;
-
-static void onsig(int)
-{
- LOGDEB("Got sig" << endl);
- dev->shouldExit();
-}
-
-static const int catchedSigs[] = {SIGINT, SIGQUIT, SIGTERM};
-
-static void setupsigs()
-{
- struct sigaction action;
- action.sa_handler = onsig;
- action.sa_flags = 0;
- sigemptyset(&action.sa_mask);
- for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++)
- if (signal(catchedSigs[i], SIG_IGN) != SIG_IGN) {
- if (sigaction(catchedSigs[i], &action, 0) < 0) {
- perror("Sigaction failed");
- }
- }
-}
// Note: if we ever need this to work without cxx11, there is this:
// http://www.tutok.sk/fastgl/callback.html
@@ -113,8 +81,9 @@
UpMpdAVTransport* avt = new UpMpdAVTransport(this);
m_services.push_back(avt);
m_services.push_back(new UpMpdConMan(this));
+ bool ohReceiver = (m_options & upmpdOhReceiver) != 0;
if (m_options & upmpdDoOH) {
- m_services.push_back(new OHProduct(this, friendlyname, has_sc2mpd));
+ m_services.push_back(new OHProduct(this, friendlyname, ohReceiver));
m_services.push_back(new OHInfo(this));
m_services.push_back(new OHTime(this));
m_services.push_back(new OHVolume(this, rdctl));
@@ -122,7 +91,7 @@
m_services.push_back(ohp);
if (avt)
avt->setOHP(ohp);
- if (has_sc2mpd) {
+ if (ohReceiver) {
m_services.push_back(new OHReceiver(this, ohp, opts.schttpport));
}
}
@@ -147,6 +116,47 @@
#include "conftree.hxx"
+static char *thisprog;
+
+static int op_flags;
+#define OPT_MOINS 0x1
+#define OPT_h 0x2
+#define OPT_p 0x4
+#define OPT_d 0x8
+#define OPT_D 0x10
+#define OPT_c 0x20
+#define OPT_l 0x40
+#define OPT_f 0x80
+#define OPT_q 0x100
+#define OPT_i 0x200
+#define OPT_P 0x400
+#define OPT_O 0x800
+
+static const char usage[] =
+ "-c configfile \t configuration file to use\n"
+ "-h host \t specify host MPD is running on\n"
+ "-p port \t specify MPD port\n"
+ "-d logfilename\t debug messages to\n"
+ "-l loglevel\t log level (0-6)\n"
+ "-D \t run as a daemon\n"
+ "-f friendlyname\t define device displayed name\n"
+ "-q 0|1\t if set, we own the mpd queue, else avoid clearing it whenever we feel like it\n"
+ "-i iface \t specify network interface name to be used for UPnP\n"
+ "-P upport \t specify port number to be used for UPnP\n"
+ "-O 0|1\t decide if we run and export the OpenHome services\n"
+ "\n"
+ ;
+
+static void
+Usage(void)
+{
+ fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
+ exit(1);
+}
+
+// The description XML document is the first thing downloaded by
+// clients and tells them what services we export, and where to find
+// them.
static string ohDesc(
"<service>"
" <serviceType>urn:av-openhome-org:service:Product:1</serviceType>"
@@ -184,6 +194,9 @@
" <eventSubURL>/evt/OHPlaylist</eventSubURL>"
"</service>"
);
+
+// We only advertise the Openhome Receiver service if the sc2mpd
+// songcast-to-mpd gateway command is available
static string ohDescReceive(
"<service>"
" <serviceType>urn:av-openhome-org:service:Receiver:1</serviceType>"
@@ -206,48 +219,6 @@
"</iconList>"
);
-static char *thisprog;
-
-static int op_flags;
-#define OPT_MOINS 0x1
-#define OPT_h 0x2
-#define OPT_p 0x4
-#define OPT_d 0x8
-#define OPT_D 0x10
-#define OPT_c 0x20
-#define OPT_l 0x40
-#define OPT_f 0x80
-#define OPT_q 0x100
-#define OPT_i 0x200
-#define OPT_P 0x400
-#define OPT_O 0x800
-
-static const char usage[] =
- "-c configfile \t configuration file to use\n"
- "-h host \t specify host MPD is running on\n"
- "-p port \t specify MPD port\n"
- "-d logfilename\t debug messages to\n"
- "-l loglevel\t log level (0-6)\n"
- "-D \t run as a daemon\n"
- "-f friendlyname\t define device displayed name\n"
- "-q 0|1\t if set, we own the mpd queue, else avoid clearing it whenever we feel like it\n"
- "-i iface \t specify network interface name to be used for UPnP\n"
- "-P upport \t specify port number to be used for UPnP\n"
- "-O 0|1\t decide if we run and export the OpenHome services\n"
- "\n"
- ;
-static void
-Usage(void)
-{
- fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
- exit(1);
-}
-
-static string myDeviceUUID;
-
-static string datadir(DATADIR "/");
-static string configdir(CONFIGDIR "/");
-
// Our XML description data. !Keep description.xml first!
static vector<const char *> xmlfilenames =
{
@@ -260,6 +231,42 @@
"OHPlaylist.xml",
};
+static const string dfltFriendlyName("UpMpd");
+
+// This is global
+string upmpdProtocolInfo;
+
+// Static for cleanup in sig handler.
+static UpnpDevice *dev;
+
+static string datadir(DATADIR "/");
+
+// Global
+string g_configfilename(CONFIGDIR "/upmpdcli.conf");
+
+// Path for the sc2mpd command, or empty
+string g_sc2mpd_path;
+
+static void onsig(int)
+{
+ LOGDEB("Got sig" << endl);
+ dev->shouldExit();
+}
+
+static const int catchedSigs[] = {SIGINT, SIGQUIT, SIGTERM};
+static void setupsigs()
+{
+ struct sigaction action;
+ action.sa_handler = onsig;
+ action.sa_flags = 0;
+ sigemptyset(&action.sa_mask);
+ for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++)
+ if (signal(catchedSigs[i], SIG_IGN) != SIG_IGN) {
+ if (sigaction(catchedSigs[i], &action, 0) < 0) {
+ perror("Sigaction failed");
+ }
+ }
+}
int main(int argc, char *argv[])
{
@@ -268,7 +275,6 @@
string mpdpassword;
string logfilename;
int loglevel(Logger::LLINF);
- string configfile;
string friendlyname(dfltFriendlyName);
bool ownqueue = true;
bool openhome = true;
@@ -287,7 +293,7 @@
if ((cp = getenv("UPMPD_FRIENDLYNAME")))
friendlyname = atoi(cp);
if ((cp = getenv("UPMPD_CONFIG")))
- configfile = cp;
+ g_configfilename = cp;
if ((cp = getenv("UPMPD_UPNPIFACE")))
iface = cp;
if ((cp = getenv("UPMPD_UPNPPORT")))
@@ -302,7 +308,7 @@
while (**argv)
switch (*(*argv)++) {
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
- configfile = *(++argv); argc--; goto b1;
+ g_configfilename = *(++argv); argc--; goto b1;
case 'D': op_flags |= OPT_D; break;
case 'd': op_flags |= OPT_d; if (argc < 2) Usage();
logfilename = *(++argv); argc--; goto b1;
@@ -340,10 +346,10 @@
UpMpd::Options opts;
string iconpath;
- if (!configfile.empty()) {
- ConfSimple config(configfile.c_str(), 1, true);
+ if (!g_configfilename.empty()) {
+ ConfSimple config(g_configfilename.c_str(), 1, true);
if (!config.ok()) {
- cerr << "Could not open config: " << configfile << endl;
+ cerr << "Could not open config: " << g_configfilename << endl;
return 1;
}
string value;
@@ -380,15 +386,27 @@
}
if (config.get("schttpport", value))
opts.schttpport = atoi(value.c_str());
+ config.get("sc2mpd", g_sc2mpd_path);
if (config.get("ohmetasleep", value))
opts.ohmetasleep = atoi(value.c_str());
}
-
if (Logger::getTheLog(logfilename) == 0) {
cerr << "Can't initialize log" << endl;
return 1;
}
Logger::getTheLog("")->setLogLevel(Logger::LogLevel(loglevel));
+
+ if (g_sc2mpd_path.empty()) {
+ // Do we have an sc2mpd command installed (for songcast)?
+ if (!ExecCmd::which("sc2mpd", g_sc2mpd_path))
+ g_sc2mpd_path.clear();
+ } else {
+ if (access(g_sc2mpd_path.c_str(), X_OK|R_OK) != 0) {
+ LOGERR("Specified path for sc2mpd: " << g_sc2mpd_path <<
+ " is not executable" << endl);
+ g_sc2mpd_path.clear();
+ }
+ }
Pidfile pidfile(pidfilename);
@@ -483,10 +501,6 @@
}
}
- // Do we have an sc2mpd command installed (for songcast)?
- string unused;
- has_sc2mpd = ExecCmd::which("sc2mpd", unused);
-
// Initialize libupnpp, and check health
LibUPnP *mylib = 0;
string hwaddr;
@@ -528,7 +542,7 @@
// Read our XML data to make it available from the virtual directory
if (openhome) {
- if (has_sc2mpd) {
+ if (!g_sc2mpd_path.empty()) {
ohxmlfilenames.push_back("OHReceiver.xml");
}
xmlfilenames.insert(xmlfilenames.end(), ohxmlfilenames.begin(),
@@ -565,7 +579,7 @@
data = regsub1("@UUID@", data, UUID);
data = regsub1("@FRIENDLYNAME@", data, friendlyname);
if (openhome) {
- if (has_sc2mpd) {
+ if (!g_sc2mpd_path.empty()) {
ohDesc += ohDescReceive;
}
data = regsub1("@OPENHOME@", data, ohDesc);
@@ -592,6 +606,8 @@
opts.options |= UpMpd::upmpdDoOH;
if (ohmetapersist)
opts.options |= UpMpd::upmpdOhMetaPersist;
+ if (!g_sc2mpd_path.empty())
+ opts.options |= UpMpd::upmpdOhReceiver;
// Initialize the UPnP device object.
UpMpd device(string("uuid:") + UUID, friendlyname,