libupnpp/cdircontent.cxx to libupnpp/control/cdircontent.cxx
File was renamed.
libupnpp/cdircontent.hxx to libupnpp/control/cdircontent.hxx
File was renamed.
libupnpp/cdirectory.cxx to libupnpp/control/cdirectory.cxx
--- a/libupnpp/cdirectory.cxx +++ b/libupnpp/control/cdirectory.cxx @@ -37,6 +37,8 @@ #include "cdirectory.hxx" #include "cdircontent.hxx" #include "discovery.hxx" +#include "soaphelp.hxx" +#include "log.hxx" namespace UPnPClient { @@ -98,84 +100,62 @@ } -class DirBResFree { -public: - IXML_Document **rqpp, **rspp; - DirBResFree(IXML_Document** _rqpp, IXML_Document **_rspp) - :rqpp(_rqpp), rspp(_rspp) - {} - ~DirBResFree() - { - if (*rqpp) - ixmlDocument_free(*rqpp); - if (*rspp) - ixmlDocument_free(*rspp); - } -}; +#if 0 +static int asyncReaddirCB(Upnp_EventType et, void *vev, void *cookie) +{ + LOGDEB("asyncReaddirCB: " << LibUPnP::evTypeAsString(et) << endl); + struct Upnp_Action_Complete *act = (struct Upnp_Action_Complete*)vev; + + LOGDEB("asyncReaddirCB: errcode " << act->ErrCode << + " cturl " << UpnpString_get_String(act->CtrlUrl) << + " actionrequest " << endl << + ixmlPrintDocument(act->ActionRequest) << endl << + " actionresult " << ixmlPrintDocument(act->ActionResult) << endl); + return 0; +} + int ret = + UpnpSendActionAsync(hdl, m_actionURL.c_str(), m_serviceType.c_str(), + 0 /*devUDN*/, request, asyncReaddirCB, 0); + sleep(10); + return -1; +#endif + int ContentDirectoryService::readDirSlice(const string& objectId, int offset, int count, UPnPDirContent& dirbuf, int *didreadp, int *totalp) { - LOGDEB("CDService::readDirSlice: objId ["<< objectId << "] offset " << + LOGDEB("CDService::readDirSlice: objId [" << objectId << "] offset " << offset << " count " << count << endl); - LibUPnP* lib = LibUPnP::getLibUPnP(); - if (lib == 0) { - LOGINF("CDService::readDir: no lib" << endl); - return UPNP_E_OUTOF_MEMORY; - } - UpnpClient_Handle hdl = lib->getclh(); - - IXML_Document *request(0); - IXML_Document *response(0); - DirBResFree cleaner(&request, &response); - // Create request - char ofbuf[100], cntbuf[100]; - sprintf(ofbuf, "%d", offset); - sprintf(cntbuf, "%d", count); - int argcnt = 6; // Some devices require an empty SortCriteria, else bad params - request = UpnpMakeAction("Browse", m_serviceType.c_str(), argcnt, - "ObjectID", objectId.c_str(), - "BrowseFlag", "BrowseDirectChildren", - "Filter", "*", - "SortCriteria", "", - "StartingIndex", ofbuf, - "RequestedCount", cntbuf, - NULL, NULL); - if (request == 0) { - LOGINF("CDService::readDir: UpnpMakeAction failed" << endl); - return UPNP_E_OUTOF_MEMORY; - } - - //cerr << "Action xml: [" << ixmlPrintDocument(request) << "]" << endl; - - int ret = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(), - 0 /*devUDN*/, request, &response); - + SoapData args(m_serviceType, "Browse"); + args("ObjectID", objectId) + ("BrowseFlag", "BrowseDirectChildren") + ("Filter", "*") + ("SortCriteria", "") + ("StartingIndex", SoapEncodeInput::i2s(offset)) + ("RequestedCount", SoapEncodeInput::i2s(count)); + + SoapArgs data; + int ret = runAction(args, data); if (ret != UPNP_E_SUCCESS) { - LOGINF("CDService::readDir: UpnpSendAction failed: " << - UpnpGetErrorMessage(ret) << endl); return ret; } - - int didread = -1; - string tbuf = ixmlwrap::getFirstElementValue(response, "NumberReturned"); - if (!tbuf.empty()) - didread = atoi(tbuf.c_str()); - - if (count == -1 || count == 0) { + int didread; + string tbuf; + if (!data.getInt("NumberReturned", &didread) || + !data.getInt("TotalMatches", totalp) || + !data.getString("Result", &tbuf)) { + LOGERR("CDService::readDir: missing elts in response" << endl); + return UPNP_E_BAD_RESPONSE; + } + + if (didread <= 0) { LOGINF("CDService::readDir: got -1 or 0 entries" << endl); return UPNP_E_BAD_RESPONSE; } - - tbuf = ixmlwrap::getFirstElementValue(response, "TotalMatches"); - if (!tbuf.empty()) - *totalp = atoi(tbuf.c_str()); - - tbuf = ixmlwrap::getFirstElementValue(response, "Result"); #if 0 cerr << "CDService::readDirSlice: count " << count << @@ -186,9 +166,9 @@ dirbuf.parse(tbuf); *didreadp = didread; + return UPNP_E_SUCCESS; } - int ContentDirectoryService::readDir(const string& objectId, UPnPDirContent& dirbuf) @@ -219,46 +199,23 @@ { LOGDEB("CDService::search: url [" << m_actionURL << "] type [" << m_serviceType << "] udn [" << m_deviceId << "] objid [" << - objectId << "] search [" << ss << "]" << endl; - - LibUPnP* lib = LibUPnP::getLibUPnP(); - if (lib == 0) { - LOGINF("CDService::search: no lib" << endl); - return UPNP_E_OUTOF_MEMORY; - } - UpnpClient_Handle hdl = lib->getclh(); - - int ret = UPNP_E_SUCCESS; - IXML_Document *request(0); - IXML_Document *response(0); + objectId << "] search [" << ss << "]" << endl); int offset = 0; int total = 1000;// Updated on first read. while (offset < total) { - DirBResFree cleaner(&request, &response); - char ofbuf[100]; - sprintf(ofbuf, "%d", offset); // Create request - int argcnt = 6; - request = UpnpMakeAction( - "Search", m_serviceType.c_str(), argcnt, - "ContainerID", objectId.c_str(), - "SearchCriteria", ss.c_str(), - "Filter", "*", - "SortCriteria", "", - "StartingIndex", ofbuf, - "RequestedCount", "0", // Setting a value here gets twonky into fits - NULL, NULL); - if (request == 0) { - LOGINF("CDService::search: UpnpMakeAction failed" << endl); - return UPNP_E_OUTOF_MEMORY; - } - - // cerr << "Action xml: [" << ixmlPrintDocument(request) << "]" << endl; - - ret = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(), - 0 /*devUDN*/, request, &response); + SoapData args(m_serviceType, "Search"); + args("ContainerID", objectId) + ("SearchCriteria", ss) + ("Filter", "*") + ("SortCriteria", "") + ("StartingIndex", SoapEncodeInput::i2s(offset)) + ("RequestedCount", "10"); + + SoapArgs data; + int ret = runAction(args, data); if (ret != UPNP_E_SUCCESS) { LOGINF("CDService::search: UpnpSendAction failed: " << @@ -267,30 +224,19 @@ } int count = -1; - string tbuf = - ixmlwrap::getFirstElementValue(response, "NumberReturned"); - if (!tbuf.empty()) - count = atoi(tbuf.c_str()); - - if (count == -1 || count == 0) { + string tbuf; + if (!data.getInt("NumberReturned", &count) || + !data.getInt("TotalMatches", &total) || + !data.getString("Result", &tbuf)) { + LOGERR("CDService::search: missing elts in response" << endl); + return UPNP_E_BAD_RESPONSE; + } + if (count <= 0) { LOGINF("CDService::search: got -1 or 0 entries" << endl); - return count == -1 ? UPNP_E_BAD_RESPONSE : UPNP_E_SUCCESS; + return count < 0 ? UPNP_E_BAD_RESPONSE : UPNP_E_SUCCESS; } offset += count; - tbuf = ixmlwrap::getFirstElementValue(response, "TotalMatches"); - if (!tbuf.empty()) - total = atoi(tbuf.c_str()); - - tbuf = ixmlwrap::getFirstElementValue(response, "Result"); - -#if 0 - cerr << "CDService::search: count " << count << - " offset " << offset << - " total " << total << endl; - cerr << " result " << tbuf << endl; -#endif - dirbuf.parse(tbuf); } @@ -300,41 +246,21 @@ int ContentDirectoryService::getSearchCapabilities(set<string>& result) { LOGDEB("CDService::getSearchCapabilities:" << endl); - LibUPnP* lib = LibUPnP::getLibUPnP(); - if (lib == 0) { - LOGINF("CDService::getSearchCapabilities: no lib" << endl); - return UPNP_E_OUTOF_MEMORY; - } - UpnpClient_Handle hdl = lib->getclh(); - - int ret = UPNP_E_SUCCESS; - IXML_Document *request(0); - IXML_Document *response(0); - - request = UpnpMakeAction("GetSearchCapabilities", m_serviceType.c_str(), - 0, - NULL, NULL); - - if (request == 0) { - LOGINF("CDService::getSearchCapa: UpnpMakeAction failed" << endl); - return UPNP_E_OUTOF_MEMORY; - } - - //cerr << "Action xml: [" << ixmlPrintDocument(request) << "]" << endl; - - ret = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(), - 0 /*devUDN*/, request, &response); - + + SoapData args(m_serviceType, "GetSearchCapabilities"); + SoapArgs data; + int ret = runAction(args, data); if (ret != UPNP_E_SUCCESS) { LOGINF("CDService::getSearchCapa: UpnpSendAction failed: " << UpnpGetErrorMessage(ret) << endl); return ret; } - //cerr << "getSearchCapa: response xml: [" << ixmlPrintDocument(response) - // << "]" << endl; - - string tbuf = ixmlwrap::getFirstElementValue(response, "SearchCaps"); - // cerr << "getSearchCapa: capa: [" << tbuf << "]" << endl; + string tbuf; + if (!data.getString("SearchCaps", &tbuf)) { + LOGERR("CDService::getSearchCaps: missing Result in response" << endl); + cerr << tbuf << endl; + return UPNP_E_BAD_RESPONSE; + } result.clear(); if (!tbuf.compare("*")) { @@ -355,44 +281,26 @@ m_serviceType << "] udn [" << m_deviceId << "] objId [" << objectId << "]" << endl); - LibUPnP* lib = LibUPnP::getLibUPnP(); - if (lib == 0) { - LOGINF("CDService::getMetadata: no lib" << endl); - return UPNP_E_OUTOF_MEMORY; - } - UpnpClient_Handle hdl = lib->getclh(); - - int ret = UPNP_E_SUCCESS; - IXML_Document *request(0); - IXML_Document *response(0); - - DirBResFree cleaner(&request, &response); - // Create request - int argcnt = 6; - request = UpnpMakeAction("Browse", m_serviceType.c_str(), argcnt, - "ObjectID", objectId.c_str(), - "BrowseFlag", "BrowseMetadata", - "Filter", "*", - "SortCriteria", "", - "StartingIndex", "0", - "RequestedCount", "1", - NULL, NULL); - if (request == 0) { - LOGINF("CDService::getmetadata: UpnpMakeAction failed" << endl); - return UPNP_E_OUTOF_MEMORY; - } - - //cerr << "Action xml: [" << ixmlPrintDocument(request) << "]" << endl; - - ret = UpnpSendAction(hdl, m_actionURL.c_str(), m_serviceType.c_str(), - 0 /*devUDN*/, request, &response); - + SoapData args(m_serviceType, "Browse"); + SoapArgs data; + args("ObjectID", objectId) + ("BrowseFlag", "BrowseMetadata") + ("Filter", "*") + ("SortCriteria", "") + ("StartingIndex", "0") + ("RequestedCount", "1"); + int ret = runAction(args, data); if (ret != UPNP_E_SUCCESS) { LOGINF("CDService::getmetadata: UpnpSendAction failed: " << UpnpGetErrorMessage(ret) << endl); return ret; } - string tbuf = ixmlwrap::getFirstElementValue(response, "Result"); + string tbuf; + if (!data.getString("Result", &tbuf)) { + LOGERR("CDService::getmetadata: missing Result in response" << endl); + return UPNP_E_BAD_RESPONSE; + } + if (dirbuf.parse(tbuf)) return UPNP_E_SUCCESS; else
libupnpp/cdirectory.hxx to libupnpp/control/cdirectory.hxx
File was renamed.
libupnpp/service.cxx to libupnpp/control/renderingcontrol.cxx
--- a/libupnpp/service.cxx +++ b/libupnpp/control/renderingcontrol.cxx @@ -15,22 +15,23 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "service.h" -#include "cdirectory.h" -#include "log.h" +#include <string> +using namespace std; + +#include "libupnpp/control/renderingcontrol.hxx" namespace UPnPClient { -Service *service_factory(const string& servicetype, - const UPnPDeviceDesc& device, - const UPnPServiceDesc& service) +const string +RenderingControl::SType("urn:schemas-upnp-org:service:RenderingControl:1"); + +// We don't include a version in comparisons, as we are satisfied with +// version 1 +bool RenderingControl::isRDCService(const string& st) { - if (ContentDirectoryService::isCDService(servicetype)) { - return new ContentDirectoryService(device, service); - } else { - LOGERR("service_factory: unknown service type " << servicetype << endl); - return 0; - } + const string::size_type sz(SType.size()-2); + return !SType.compare(0, sz, st, 0, sz); } -} + +};
libupnpp/service.hxx to libupnpp/control/service.hxx
--- a/libupnpp/service.hxx +++ b/libupnpp/control/service.hxx @@ -19,7 +19,11 @@ #include <string> -#include "upnpp_p.hxx" +#include <upnp/ixml.h> + +#include "libupnpp/soaphelp.hxx" +#include "libupnpp/upnpp_p.hxx" +#include "libupnpp/description.hxx" namespace UPnPClient { @@ -32,6 +36,7 @@ Service(const UPnPDeviceDesc& device, const UPnPServiceDesc& service) : m_actionURL(caturl(device.URLBase, service.controlURL)), + m_eventURL(caturl(device.URLBase, service.eventSubURL)), m_serviceType(service.serviceType), m_deviceId(device.UDN), m_friendlyName(device.friendlyName), @@ -50,8 +55,12 @@ /** Return my root device id */ std::string getDeviceId() const {return m_deviceId;} + int runAction(const SoapEncodeInput& args, SoapDecodeOutput& data); + protected: + std::string m_actionURL; + std::string m_eventURL; std::string m_serviceType; std::string m_deviceId; std::string m_friendlyName;