00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "autoconfig.h"
00034 #endif
00035
00036 #include "upnp_cds.h"
00037 #include "server.h"
00038 #include "storage.h"
00039
00040 using namespace zmm;
00041 using namespace mxml;
00042
00043 void ContentDirectoryService::upnp_action_Browse(Ref<ActionRequest> request)
00044 {
00045 log_debug("start\n");
00046 Ref<Storage> storage = Storage::getInstance();
00047
00048 Ref<Element> req = request->getRequest();
00049
00050 String objID = req->getChildText(_("ObjectID"));
00051 int objectID;
00052 String BrowseFlag = req->getChildText(_("BrowseFlag"));
00053
00054 String StartingIndex = req->getChildText(_("StartingIndex"));
00055 String RequestedCount = req->getChildText(_("RequestedCount"));
00056
00057
00058
00059
00060
00061
00062 if (objID == nil)
00063 throw UpnpException(UPNP_E_NO_SUCH_ID, _("empty object id"));
00064 else
00065 objectID = objID.toInt();
00066
00067 unsigned int flag = BROWSE_ITEMS | BROWSE_CONTAINERS | BROWSE_EXACT_CHILDCOUNT;
00068
00069 if(BrowseFlag == "BrowseDirectChildren")
00070 flag |= BROWSE_DIRECT_CHILDREN;
00071 else if (BrowseFlag != "BrowseMetadata")
00072 throw UpnpException(UPNP_SOAP_E_INVALID_ARGS,
00073 _("invalid browse flag: ") + BrowseFlag);
00074
00075 Ref<CdsObject> parent = storage->loadObject(objectID);
00076 if ((parent->getClass() == UPNP_DEFAULT_CLASS_MUSIC_ALBUM) ||
00077 (parent->getClass() == UPNP_DEFAULT_CLASS_PLAYLIST_CONTAINER))
00078 flag |= BROWSE_TRACK_SORT;
00079
00080 if (ConfigManager::getInstance()->getBoolOption(CFG_SERVER_HIDE_PC_DIRECTORY))
00081 flag |= BROWSE_HIDE_FS_ROOT;
00082
00083 Ref<BrowseParam> param(new BrowseParam(objectID, flag));
00084
00085 param->setStartingIndex(StartingIndex.toInt());
00086 param->setRequestedCount(RequestedCount.toInt());
00087
00088 Ref<Array<CdsObject> > arr;
00089
00090 try
00091 {
00092 arr = storage->browse(param);
00093 }
00094 catch (Exception e)
00095 {
00096 throw UpnpException(UPNP_E_NO_SUCH_ID, _("no such object"));
00097 }
00098
00099 Ref<Element> didl_lite (new Element(_("DIDL-Lite")));
00100 didl_lite->setAttribute(_(XML_NAMESPACE_ATTR),
00101 _(XML_DIDL_LITE_NAMESPACE));
00102 didl_lite->setAttribute(_(XML_DC_NAMESPACE_ATTR),
00103 _(XML_DC_NAMESPACE));
00104 didl_lite->setAttribute(_(XML_UPNP_NAMESPACE_ATTR),
00105 _(XML_UPNP_NAMESPACE));
00106
00107 Ref<ConfigManager> cfg = ConfigManager::getInstance();
00108
00109 for(int i = 0; i < arr->size(); i++)
00110 {
00111 Ref<CdsObject> obj = arr->get(i);
00112 if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_ENABLED) &&
00113 obj->getFlag(OBJECT_FLAG_PLAYED))
00114 {
00115 String title = obj->getTitle();
00116 if (cfg->getBoolOption(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING_MODE_PREPEND))
00117 title = cfg->getOption(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING) + title;
00118 else
00119 title = title + cfg->getOption(CFG_SERVER_EXTOPTS_MARK_PLAYED_ITEMS_STRING);
00120
00121 obj->setTitle(title);
00122 }
00123
00124 Ref<Element> didl_object = UpnpXML_DIDLRenderObject(obj, false, stringLimit);
00125
00126 didl_lite->appendElementChild(didl_object);
00127 }
00128
00129 Ref<Element> response;
00130 response = UpnpXML_CreateResponse(request->getActionName(), serviceType);
00131
00132 response->appendTextChild(_("Result"), didl_lite->print());
00133 response->appendTextChild(_("NumberReturned"), String::from(arr->size()));
00134 response->appendTextChild(_("TotalMatches"), String::from(param->getTotalMatches()));
00135 response->appendTextChild(_("UpdateID"), String::from(systemUpdateID));
00136
00137 request->setResponse(response);
00138 log_debug("end\n");
00139 }
00140
00141 void ContentDirectoryService::upnp_action_GetSearchCapabilities(Ref<ActionRequest> request)
00142 {
00143 log_debug("start\n");
00144
00145 Ref<Element> response;
00146 response = UpnpXML_CreateResponse(request->getActionName(), serviceType);
00147 response->appendTextChild(_("SearchCaps"), _(""));
00148
00149 request->setResponse(response);
00150
00151 log_debug("end\n");
00152 }
00153
00154 void ContentDirectoryService::upnp_action_GetSortCapabilities(Ref<ActionRequest> request)
00155 {
00156 log_debug("start\n");
00157
00158 Ref<Element> response;
00159 response = UpnpXML_CreateResponse(request->getActionName(), serviceType);
00160 response->appendTextChild(_("SortCaps"), _(""));
00161
00162 request->setResponse(response);
00163
00164 log_debug("end\n");
00165 }
00166
00167 void ContentDirectoryService::upnp_action_GetSystemUpdateID(Ref<ActionRequest> request)
00168 {
00169 log_debug("start\n");
00170
00171 Ref<Element> response;
00172 response = UpnpXML_CreateResponse(request->getActionName(), serviceType);
00173 response->appendTextChild(_("Id"), String::from(systemUpdateID));
00174
00175 request->setResponse(response);
00176
00177 log_debug("end\n");
00178 }
00179
00180 void ContentDirectoryService::process_action_request(Ref<ActionRequest> request)
00181 {
00182 log_debug("start\n");
00183
00184 if (request->getActionName() == "Browse")
00185 {
00186 upnp_action_Browse(request);
00187 }
00188 else if (request->getActionName() == "GetSearchCapabilities")
00189 {
00190 upnp_action_GetSearchCapabilities(request);
00191 }
00192 else if (request->getActionName() == "GetSortCapabilities")
00193 {
00194 upnp_action_GetSortCapabilities(request);
00195 }
00196 else if (request->getActionName() == "GetSystemUpdateID")
00197 {
00198 upnp_action_GetSystemUpdateID(request);
00199 }
00200 else
00201 {
00202
00203 log_debug("unrecognized action %s\n",
00204 request->getActionName().c_str());
00205 request->setErrorCode(UPNP_E_INVALID_ACTION);
00206
00207 }
00208
00209 log_debug("ContentDirectoryService::process_action_request: end\n");
00210 }