|
a/upmpd/upmpd.cxx |
|
b/upmpd/upmpd.cxx |
|
... |
|
... |
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
16 |
*/
|
16 |
*/
|
17 |
|
17 |
|
18 |
#include <stdio.h>
|
18 |
#include <stdio.h>
|
19 |
#include <stdlib.h>
|
19 |
#include <stdlib.h>
|
|
|
20 |
#include <unistd.h>
|
20 |
|
21 |
|
21 |
#include <string>
|
22 |
#include <string>
|
22 |
#include <iostream>
|
23 |
#include <iostream>
|
23 |
#include <sstream>
|
24 |
#include <sstream>
|
24 |
#include <vector>
|
25 |
#include <vector>
|
|
... |
|
... |
624 |
MpdStatus::State st = mpds.state;
|
625 |
MpdStatus::State st = mpds.state;
|
625 |
// Have to tell mpd which track to play, else it will keep on
|
626 |
// Have to tell mpd which track to play, else it will keep on
|
626 |
// the previous despite of the insertion. The UPnP docs say
|
627 |
// the previous despite of the insertion. The UPnP docs say
|
627 |
// that setAVTransportURI should not change the transport
|
628 |
// that setAVTransportURI should not change the transport
|
628 |
// state (pause/stop stay pause/stop) but it seems that some clients
|
629 |
// state (pause/stop stay pause/stop) but it seems that some clients
|
629 |
// expect that the track will start playing so we let it play.
|
630 |
// expect that the track will start playing.
|
630 |
// Needs to be revisited after seeing more clients. For now try to
|
631 |
// Needs to be revisited after seeing more clients. For now try to
|
631 |
// preserve state as per standard.
|
632 |
// preserve state as per standard.
|
632 |
// Audionet: issues a Play
|
633 |
// Audionet: issues a Play
|
633 |
// BubbleUpnp: issues a Play
|
634 |
// BubbleUpnp: issues a Play
|
634 |
// MediaHouse: no setnext, Play
|
635 |
// MediaHouse: no setnext, Play
|
|
... |
|
... |
931 |
}
|
932 |
}
|
932 |
|
933 |
|
933 |
|
934 |
|
934 |
/////////////////////////////////////////////////////////////////////
|
935 |
/////////////////////////////////////////////////////////////////////
|
935 |
// Main program
|
936 |
// Main program
|
|
|
937 |
|
|
|
938 |
#include "conftree.hxx"
|
|
|
939 |
|
936 |
static char *thisprog;
|
940 |
static char *thisprog;
|
937 |
|
941 |
|
938 |
static int op_flags;
|
942 |
static int op_flags;
|
939 |
#define OPT_MOINS 0x1
|
943 |
#define OPT_MOINS 0x1
|
940 |
#define OPT_h 0x2
|
944 |
#define OPT_h 0x2
|
941 |
#define OPT_p 0x4
|
945 |
#define OPT_p 0x4
|
942 |
#define OPT_d 0x8
|
946 |
#define OPT_d 0x8
|
|
|
947 |
#define OPT_D 0x10
|
|
|
948 |
#define OPT_c 0x20
|
|
|
949 |
#define OPT_l 0x40
|
943 |
|
950 |
|
944 |
static const char usage[] =
|
951 |
static const char usage[] =
|
|
|
952 |
"-c configfile \t configuration file to use\n"
|
945 |
"-h host \t specify host MPD is running on\n"
|
953 |
"-h host \t specify host MPD is running on\n"
|
946 |
"-i port \t specify MPD port\n"
|
954 |
"-i port \t specify MPD port\n"
|
947 |
"-d logfilename\t debug messages to\n"
|
955 |
"-d logfilename\t debug messages to\n"
|
|
|
956 |
"-l loglevel\t log level (0-6)\n"
|
|
|
957 |
"-D \t stay in foreground\n"
|
948 |
" \n\n"
|
958 |
" \n\n"
|
949 |
;
|
959 |
;
|
950 |
static void
|
960 |
static void
|
951 |
Usage(void)
|
961 |
Usage(void)
|
952 |
{
|
962 |
{
|
|
... |
|
... |
954 |
exit(1);
|
964 |
exit(1);
|
955 |
}
|
965 |
}
|
956 |
|
966 |
|
957 |
static string myDeviceUUID;
|
967 |
static string myDeviceUUID;
|
958 |
|
968 |
|
959 |
static string datadir("upmpd/");
|
969 |
static string datadir(DATADIR "/");
|
|
|
970 |
static string configdir(CONFIGDIR "/");
|
960 |
|
971 |
|
961 |
int main(int argc, char *argv[])
|
972 |
int main(int argc, char *argv[])
|
962 |
{
|
973 |
{
|
963 |
string mpdhost("localhost");
|
974 |
string mpdhost("localhost");
|
964 |
int mpdport = 6600;
|
975 |
int mpdport = 6600;
|
965 |
string upnplogfilename("/tmp/upmpd_libupnp.log");
|
976 |
string upnplogfilename("/tmp/upmpd_libupnp.log");
|
|
|
977 |
string logfilename("");
|
|
|
978 |
int loglevel(upnppdebug::Logger::LLDEB);
|
|
|
979 |
string configfile;
|
966 |
|
980 |
|
967 |
const char *cp;
|
981 |
const char *cp;
|
968 |
if (cp = getenv("UPMPD_HOST"))
|
982 |
if (cp = getenv("UPMPD_HOST"))
|
969 |
mpdhost = cp;
|
983 |
mpdhost = cp;
|
970 |
if (cp = getenv("UPMPD_PORT"))
|
984 |
if (cp = getenv("UPMPD_PORT"))
|
971 |
mpdport = atoi(cp);
|
985 |
mpdport = atoi(cp);
|
|
|
986 |
if (cp = getenv("UPMPD_CONFIG"))
|
|
|
987 |
configfile = cp;
|
972 |
|
988 |
|
973 |
thisprog = argv[0];
|
989 |
thisprog = argv[0];
|
974 |
argc--; argv++;
|
990 |
argc--; argv++;
|
975 |
while (argc > 0 && **argv == '-') {
|
991 |
while (argc > 0 && **argv == '-') {
|
976 |
(*argv)++;
|
992 |
(*argv)++;
|
977 |
if (!(**argv))
|
993 |
if (!(**argv))
|
978 |
Usage();
|
994 |
Usage();
|
979 |
while (**argv)
|
995 |
while (**argv)
|
980 |
switch (*(*argv)++) {
|
996 |
switch (*(*argv)++) {
|
|
|
997 |
case 'D': op_flags |= OPT_D; break;
|
|
|
998 |
case 'c': op_flags |= OPT_c; if (argc < 2) Usage();
|
|
|
999 |
configfile = *(++argv); argc--; goto b1;
|
|
|
1000 |
case 'd': op_flags |= OPT_d; if (argc < 2) Usage();
|
|
|
1001 |
logfilename = *(++argv); argc--; goto b1;
|
981 |
case 'h': op_flags |= OPT_h; if (argc < 2) Usage();
|
1002 |
case 'h': op_flags |= OPT_h; if (argc < 2) Usage();
|
982 |
mpdhost = *(++argv); argc--;
|
1003 |
mpdhost = *(++argv); argc--; goto b1;
|
983 |
goto b1;
|
1004 |
case 'l': op_flags |= OPT_l; if (argc < 2) Usage();
|
|
|
1005 |
loglevel = atoi(*(++argv)); argc--; goto b1;
|
984 |
case 'p': op_flags |= OPT_p; if (argc < 2) Usage();
|
1006 |
case 'p': op_flags |= OPT_p; if (argc < 2) Usage();
|
985 |
mpdport = atoi(*(++argv)); argc--;
|
1007 |
mpdport = atoi(*(++argv)); argc--; goto b1;
|
986 |
goto b1;
|
|
|
987 |
default: Usage(); break;
|
1008 |
default: Usage(); break;
|
988 |
}
|
1009 |
}
|
989 |
b1: argc--; argv++;
|
1010 |
b1: argc--; argv++;
|
990 |
}
|
1011 |
}
|
991 |
|
1012 |
|
992 |
if (argc != 0)
|
1013 |
if (argc != 0)
|
993 |
Usage();
|
1014 |
Usage();
|
994 |
|
1015 |
|
|
|
1016 |
if (!configfile.empty()) {
|
|
|
1017 |
ConfSimple config(configfile.c_str(), 1, true);
|
|
|
1018 |
if (!config.ok()) {
|
|
|
1019 |
cerr << "Could not open config: " << configfile << endl;
|
|
|
1020 |
return 1;
|
|
|
1021 |
}
|
|
|
1022 |
string value;
|
|
|
1023 |
if (!(op_flags & OPT_d))
|
|
|
1024 |
config.get("logfilename", logfilename);
|
|
|
1025 |
if (!(op_flags & OPT_l) && config.get("loglevel", value))
|
|
|
1026 |
loglevel = atoi(value.c_str());
|
|
|
1027 |
if (!(op_flags & OPT_h))
|
|
|
1028 |
config.get("mpdhost", mpdhost);
|
|
|
1029 |
if (!(op_flags & OPT_p) && config.get("mpdport", value)) {
|
|
|
1030 |
mpdport = atoi(value.c_str());
|
|
|
1031 |
}
|
|
|
1032 |
}
|
|
|
1033 |
|
|
|
1034 |
if (upnppdebug::Logger::getTheLog(logfilename) == 0) {
|
|
|
1035 |
cerr << "Can't initialize log" << endl;
|
|
|
1036 |
return 1;
|
|
|
1037 |
}
|
|
|
1038 |
upnppdebug::Logger::getTheLog("")->setLogLevel(upnppdebug::Logger::LogLevel(loglevel));
|
|
|
1039 |
|
|
|
1040 |
if (!(op_flags & OPT_D)) {
|
|
|
1041 |
if (daemon(1, 0)) {
|
|
|
1042 |
LOGFAT("Daemon failed: errno " << errno << endl);
|
|
|
1043 |
return 1;
|
|
|
1044 |
}
|
|
|
1045 |
}
|
|
|
1046 |
|
995 |
// Initialize libupnpp, and check health
|
1047 |
// Initialize libupnpp, and check health
|
996 |
LibUPnP *mylib = LibUPnP::getLibUPnP(true);
|
1048 |
LibUPnP *mylib = LibUPnP::getLibUPnP(true);
|
997 |
if (!mylib) {
|
1049 |
if (!mylib) {
|
998 |
LOGFAT(" Can't get LibUPnP" << endl);
|
1050 |
LOGFAT("Can't get LibUPnP" << endl);
|
999 |
return 1;
|
1051 |
return 1;
|
1000 |
}
|
1052 |
}
|
1001 |
if (!mylib->ok()) {
|
1053 |
if (!mylib->ok()) {
|
1002 |
LOGFAT("Lib init failed: " <<
|
1054 |
LOGFAT("Lib init failed: " <<
|
1003 |
mylib->errAsString("main", mylib->getInitError()) << endl);
|
1055 |
mylib->errAsString("main", mylib->getInitError()) << endl);
|
|
... |
|
... |
1031 |
filename = datadir + "RenderingControl.xml";
|
1083 |
filename = datadir + "RenderingControl.xml";
|
1032 |
if (!file_to_string(filename, rdc_scdp, &reason)) {
|
1084 |
if (!file_to_string(filename, rdc_scdp, &reason)) {
|
1033 |
LOGFAT("Failed reading " << filename << " : " << reason << endl);
|
1085 |
LOGFAT("Failed reading " << filename << " : " << reason << endl);
|
1034 |
return 1;
|
1086 |
return 1;
|
1035 |
}
|
1087 |
}
|
|
|
1088 |
|
1036 |
string avt_scdp;
|
1089 |
string avt_scdp;
|
1037 |
filename = datadir + "AVTransport.xml";
|
1090 |
filename = datadir + "AVTransport.xml";
|
1038 |
if (!file_to_string(filename, avt_scdp, &reason)) {
|
1091 |
if (!file_to_string(filename, avt_scdp, &reason)) {
|
1039 |
LOGFAT("Failed reading " << filename << " : " << reason << endl);
|
1092 |
LOGFAT("Failed reading " << filename << " : " << reason << endl);
|
1040 |
return 1;
|
1093 |
return 1;
|