--- a/upexplo/upexplo.cxx
+++ b/upexplo/upexplo.cxx
@@ -29,6 +29,7 @@
#include "libupnpp/upnpplib.hxx"
#include "libupnpp/discovery.hxx"
#include "libupnpp/description.hxx"
+#include "libupnpp/control/service.hxx"
#include "libupnpp/control/cdirectory.hxx"
#include "libupnpp/control/mediarenderer.hxx"
#include "libupnpp/control/renderingcontrol.hxx"
@@ -38,14 +39,14 @@
void listServers()
{
cout << "Content Directories:" << endl;
- vector<ContentDirectoryService> dirservices;
+ vector<CDSH> dirservices;
if (!ContentDirectoryService::getServices(dirservices)) {
cerr << "listDirServices failed" << endl;
return;
}
- for (vector<ContentDirectoryService>::iterator it = dirservices.begin();
+ for (vector<CDSH>::iterator it = dirservices.begin();
it != dirservices.end(); it++) {
- cout << it->getFriendlyName() << endl;
+ cout << (*it)->getFriendlyName() << endl;
}
cout << endl;
}
@@ -64,59 +65,125 @@
cout << endl;
}
-void getsetVolume(const string& friendlyName, int volume = -1)
-{
+class MReporter : public UPnPClient::VarEventReporter {
+public:
+ void changed(const char *nm, int value)
+ {
+ cout << "Changed: " << nm << " : " << value << endl;
+ }
+ void changed(const char *nm, const char *value)
+ {
+ cout << "Changed: " << nm << " : " << value << endl;
+ }
+
+ void changed(const char *nm, UPnPDirContent meta)
+ {
+ string s("NO CONTENT");
+ if (meta.m_items.size() > 0) {
+ s = meta.m_items[0].dump();
+ }
+ cout << "Changed: " << nm << " : " << s << endl;
+ }
+
+};
+
+MRDH getRenderer(const string& friendlyName)
+{
+ MRDH rdr;
vector<UPnPDeviceDesc> vdds;
if (!MediaRenderer::getDeviceDescs(vdds, friendlyName)) {
cerr << "MediaRenderer::getDeviceDescs" << endl;
- return;
+ return rdr;
}
if (vdds.size() == 0) {
- cerr << "Player not found" <<endl;
- return;
+ cerr << "Player not found" << endl;
+ return rdr;
} else if (vdds.size() > 1) {
cerr << "Multiple players found" << endl;
- return;
+ return rdr;
}
UPnPDeviceDesc& dev = vdds[0];
- RenderingControl ctl;
- bool found = false;
- for (auto& entry : dev.services) {
- if (RenderingControl::isRDCService(entry.serviceType)) {
- ctl = RenderingControl(dev, entry);
- found = true;
- }
- }
- if (!found) {
- cerr << "Rendering control service not found in device" << endl;
- return;
- }
+ return MRDH(new MediaRenderer(dev));
+}
+
+void getsetVolume(const string& friendlyName, int volume = -1)
+{
+ MRDH rdr = getRenderer(friendlyName);
+ if (!rdr) {
+ return;
+ }
+
+ RDCH rdc = rdr->rdc();
+ if (!rdc) {
+ cerr << "Device has no RenderingControl service" << endl;
+ return;
+ }
+
+ MReporter reporter;
+ rdc->installReporter(&reporter);
+
if (volume == -1) {
- volume = ctl.getVolume();
- cout << "Current volume: " << volume << endl;
+ volume = rdc->getVolume();
+ cout << "Current volume: " << volume << " reporter " <<
+ rdc->getReporter() << endl;
#warning remove
- sleep(200);
+ while (true)
+ sleep(20);
return;
} else {
- if ((volume = ctl.setVolume(volume)) != 0) {
+ if ((volume = rdc->setVolume(volume)) != 0) {
cerr << "Error setting volume: " << volume << endl;
return;
}
}
}
+void tpPlayStop(const string& friendlyName, bool doplay)
+{
+ MRDH rdr = getRenderer(friendlyName);
+ if (!rdr) {
+ return;
+ }
+ AVTH avt = rdr->avt();
+ if (!avt) {
+ cerr << "Device has no AVTransport service" << endl;
+ return;
+ }
+ MReporter reporter;
+ avt->installReporter(&reporter);
+ int ret;
+ if (doplay) {
+ ret = avt->play();
+ } else {
+ ret = avt->stop();
+ }
+ if (ret != 0) {
+ cerr << "Operation failed: code: " << ret << endl;
+ }
+#warning remove
+ while (true) {
+ AVTransport::PositionInfo info;
+ if (avt->getPositionInfo(info)) {
+ cerr << "getPositionInfo failed. Code " << ret << endl;
+ } else {
+ cout << info.trackmeta.m_title << " reltime " << info.reltime << endl;
+ }
+ sleep(2);
+ }
+}
+
void readdir(LibUPnP *lib, const string& friendlyName, const string& cid)
{
cout << "readdir: [" << friendlyName << "] [" << cid << "]" << endl;
- ContentDirectoryService server;
+ CDSH server;
if (!ContentDirectoryService::getServerByName(friendlyName, server)) {
cerr << "Server not found" << endl;
return;
}
UPnPDirContent dirbuf;
- int code = server.readDir(cid, dirbuf);
+ int code = server->readDir(cid, dirbuf);
if (code) {
cerr << LibUPnP::errAsString("readdir", code) << endl;
return;
@@ -134,13 +201,13 @@
void getMetadata(LibUPnP *lib, const string& friendlyName, const string& cid)
{
cout << "getMeta: [" << friendlyName << "] [" << cid << "]" << endl;
- ContentDirectoryService server;
+ CDSH server;
if (!ContentDirectoryService::getServerByName(friendlyName, server)) {
cerr << "Server not found" << endl;
return;
}
UPnPDirContent dirbuf;
- int code = server.getMetadata(cid, dirbuf);
+ int code = server->getMetadata(cid, dirbuf);
if (code) {
cerr << LibUPnP::errAsString("readdir", code) << endl;
return;
@@ -158,14 +225,14 @@
void search(LibUPnP *lib, const string& friendlyName, const string& ss)
{
cout << "search: [" << friendlyName << "] [" << ss << "]" << endl;
- ContentDirectoryService server;
+ CDSH server;
if (!ContentDirectoryService::getServerByName(friendlyName, server)) {
cerr << "Server not found" << endl;
return;
}
UPnPDirContent dirbuf;
string cid("0");
- int code = server.search(cid, ss, dirbuf);
+ int code = server->search(cid, ss, dirbuf);
if (code) {
cerr << LibUPnP::errAsString("search", code) << endl;
return;
@@ -183,13 +250,13 @@
void getSearchCaps(LibUPnP *lib, const string& friendlyName)
{
cout << "getSearchCaps: [" << friendlyName << "]" << endl;
- ContentDirectoryService server;
+ CDSH server;
if (!ContentDirectoryService::getServerByName(friendlyName, server)) {
cerr << "Server not found" << endl;
return;
}
set<string> capa;
- int code = server.getSearchCapabilities(capa);
+ int code = server->getSearchCapabilities(capa);
if (code) {
cerr << LibUPnP::errAsString("readdir", code) << endl;
return;
@@ -214,6 +281,7 @@
" -c <server> get search capabilities\n"
" -v <renderer> get volume\n"
" -V <renderer> <volume> set volume\n"
+ " -p <renderer> 1|0 play/stop\n"
" \n\n"
;
static void
@@ -231,12 +299,14 @@
#define OPT_m 0x20
#define OPT_v 0x40
#define OPT_V 0x80
+#define OPT_p 0x100
int main(int argc, char *argv[])
{
string fname;
string arg;
int volume = -1;
+ int iarg = 0;
thisprog = argv[0];
argc--; argv++;
@@ -255,6 +325,10 @@
case 'm': op_flags |= OPT_m; if (argc < 3) Usage();
fname = *(++argv);argc--;
arg = *(++argv);argc--;
+ goto b1;
+ case 'p': op_flags |= OPT_p; if (argc < 3) Usage();
+ fname = *(++argv);argc--;
+ iarg = atoi(*(++argv)); argc--;
goto b1;
case 'r': op_flags |= OPT_r; if (argc < 3) Usage();
fname = *(++argv);argc--;
@@ -320,6 +394,8 @@
getsetVolume(fname, volume);
} else if ((op_flags & OPT_v)) {
getsetVolume(fname);
+ } else if ((op_flags & OPT_p)) {
+ tpPlayStop(fname, iarg);
} else {
Usage();
}