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_xml.h"
00037 #include "server.h"
00038 #include "cds_resource_manager.h"
00039 #include "common.h"
00040 #include "config_manager.h"
00041 #include "metadata_handler.h"
00042
00043 using namespace zmm;
00044 using namespace mxml;
00045
00046 Ref<Element> UpnpXML_CreateResponse(String actionName, String serviceType)
00047 {
00048 Ref<Element> response(new Element(_("u:") + actionName +
00049 "Response"));
00050 response->setAttribute(_("xmlns:u"), serviceType);
00051
00052 return response;
00053 }
00054
00055 Ref<Element> UpnpXML_DIDLRenderObject(Ref<CdsObject> obj, bool renderActions, int stringLimit)
00056 {
00057 Ref<Element> result(new Element(_("")));
00058
00059 result->setAttribute(_("id"), String::from(obj->getID()));
00060 result->setAttribute(_("parentID"), String::from(obj->getParentID()));
00061 result->setAttribute(_("restricted"), obj->isRestricted() ? _("1") : _("0"));
00062
00063 String tmp = obj->getTitle();
00064
00065 if ((stringLimit > 0) && (tmp.length() > stringLimit))
00066 {
00067 tmp = tmp.substring(0, getValidUTF8CutPosition(tmp, stringLimit-3));
00068 tmp = tmp + _("...");
00069 }
00070
00071 result->appendTextChild(_("dc:title"), tmp);
00072
00073 result->appendTextChild(_("upnp:class"), obj->getClass());
00074
00075 int objectType = obj->getObjectType();
00076 if (IS_CDS_ITEM(objectType))
00077 {
00078 Ref<CdsItem> item = RefCast(obj, CdsItem);
00079
00080 Ref<Dictionary> meta = obj->getMetadata();
00081 Ref<Array<DictionaryElement> > elements = meta->getElements();
00082 int len = elements->size();
00083
00084 String key;
00085 String upnp_class = obj->getClass();
00086
00087 for (int i = 0; i < len; i++)
00088 {
00089 Ref<DictionaryElement> el = elements->get(i);
00090 key = el->getKey();
00091 if (key == MetadataHandler::getMetaFieldName(M_DESCRIPTION))
00092 {
00093 tmp = el->getValue();
00094 if ((stringLimit > 0) && (tmp.length() > stringLimit))
00095 {
00096 tmp = tmp.substring(0,
00097 getValidUTF8CutPosition(tmp, stringLimit-3));
00098 tmp = tmp + _("...");
00099 }
00100 result->appendTextChild(key, tmp);
00101 }
00102 else if (key == MetadataHandler::getMetaFieldName(M_TRACKNUMBER))
00103 {
00104 if (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_TRACK)
00105 result->appendTextChild(key, el->getValue());
00106 }
00107 else if ((key != MetadataHandler::getMetaFieldName(M_TITLE)) ||
00108 ((key == MetadataHandler::getMetaFieldName(M_TRACKNUMBER)) &&
00109 (upnp_class == UPNP_DEFAULT_CLASS_MUSIC_TRACK)))
00110 result->appendTextChild(key, el->getValue());
00111 }
00112
00113
00114
00115
00116 CdsResourceManager::addResources(item, result);
00117
00118 result->setName(_("item"));
00119 }
00120 else if (IS_CDS_CONTAINER(objectType))
00121 {
00122 Ref<CdsContainer> cont = RefCast(obj, CdsContainer);
00123
00124 result->setName(_("container"));
00125 int childCount = cont->getChildCount();
00126 if (childCount >= 0)
00127 result->setAttribute(_("childCount"), String::from(childCount));
00128
00129 }
00130
00131 if (renderActions && IS_CDS_ACTIVE_ITEM(objectType))
00132 {
00133 Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
00134 result->appendTextChild(_("action"), aitem->getAction());
00135 result->appendTextChild(_("state"), aitem->getState());
00136 result->appendTextChild(_("location"), aitem->getLocation());
00137 result->appendTextChild(_("mime-type"), aitem->getMimeType());
00138 }
00139
00140
00141
00142 return result;
00143 }
00144
00145 void UpnpXML_DIDLUpdateObject(Ref<CdsObject> obj, String text)
00146 {
00147 Ref<Parser> parser(new Parser());
00148 Ref<Element> root = parser->parseString(text)->getRoot();
00149 int objectType = obj->getObjectType();
00150
00151 if (IS_CDS_ACTIVE_ITEM(objectType))
00152 {
00153 Ref<CdsActiveItem> aitem = RefCast(obj, CdsActiveItem);
00154
00155 String title = root->getChildText(_("dc:title"));
00156 if (title != nil && title != "")
00157 aitem->setTitle(title);
00158
00160 String description = root->getChildText(_("dc:description"));
00161 if (description == nil)
00162 description = _("");
00163 aitem->setMetadata(MetadataHandler::getMetaFieldName(M_DESCRIPTION),
00164 description);
00165
00166 String location = root->getChildText(_("location"));
00167 if (location != nil && location != "")
00168 aitem->setLocation(location);
00169
00170 String mimeType = root->getChildText(_("mime-type"));
00171 if (mimeType != nil && mimeType != "")
00172 aitem->setMimeType(mimeType);
00173
00174 String action = root->getChildText(_("action"));
00175 if (action != nil && action != "")
00176 aitem->setAction(action);
00177
00178 String state = root->getChildText(_("state"));
00179 if (state == nil)
00180 state = _("");
00181 aitem->setState(state);
00182 }
00183
00184 }
00185
00186 Ref<Element> UpnpXML_CreateEventPropertySet()
00187 {
00188 Ref<Element> propset(new Element(_("e:propertyset")));
00189 propset->setAttribute(_("xmlns:e"), _("urn:schemas-upnp-org:event-1-0"));
00190
00191 Ref<Element> property(new Element(_("e:property")));
00192
00193 propset->appendElementChild(property);
00194 return propset;
00195 }
00196
00197 Ref<Element> UpnpXML_RenderDeviceDescription(String presentationURL)
00198 {
00199
00200 log_debug("start\n");
00201 Ref<ConfigManager> config = ConfigManager::getInstance();
00202
00203 Ref<Element> root(new Element(_("root")));
00204 root->setAttribute(_("xmlns"), _(DESC_DEVICE_NAMESPACE));
00205
00206 Ref<Element> specVersion(new Element(_("specVersion")));
00207 specVersion->appendTextChild(_("major"), _(DESC_SPEC_VERSION_MAJOR));
00208 specVersion->appendTextChild(_("minor"), _(DESC_SPEC_VERSION_MINOR));
00209
00210 root->appendElementChild(specVersion);
00211
00212 Ref<Element> device(new Element(_("device")));
00213
00214 #ifdef EXTEND_PROTOCOLINFO
00215 if (config->getBoolOption(CFG_SERVER_EXTEND_PROTOCOLINFO))
00216 {
00217
00218 Ref<Element> DLNADOC(new Element(_("dlna:X_DLNADOC")));
00219 DLNADOC->setText(_("DMS-1.50"));
00220
00221 DLNADOC->setAttribute(_("xmlns:dlna"),
00222 _("urn:schemas-dlna-org:device-1-0"));
00223 device->appendElementChild(DLNADOC);
00224 }
00225 #endif
00226
00227 device->appendTextChild(_("deviceType"), _(DESC_DEVICE_TYPE));
00228 if (!string_ok(presentationURL))
00229 device->appendTextChild(_("presentationURL"), _("/"));
00230 else
00231 device->appendTextChild(_("presentationURL"), presentationURL);
00232
00233 device->appendTextChild(_("friendlyName"),
00234 config->getOption(CFG_SERVER_NAME));
00235
00236 device->appendTextChild(_("manufacturer"), _(DESC_MANUFACTURER));
00237 device->appendTextChild(_("manufacturerURL"),
00238 config->getOption(CFG_SERVER_MANUFACTURER_URL));
00239 device->appendTextChild(_("modelDescription"),
00240 config->getOption(CFG_SERVER_MODEL_DESCRIPTION));
00241 device->appendTextChild(_("modelName"),
00242 config->getOption(CFG_SERVER_MODEL_NAME));
00243 device->appendTextChild(_("modelNumber"),
00244 config->getOption(CFG_SERVER_MODEL_NUMBER));
00245 device->appendTextChild(_("serialNumber"),
00246 config->getOption(CFG_SERVER_SERIAL_NUMBER));
00247 device->appendTextChild(_("UDN"), config->getOption(CFG_SERVER_UDN));
00248
00249 Ref<Element> iconList(new Element(_("iconList")));
00250
00251 Ref<Element> icon120_png(new Element(_("icon")));
00252 icon120_png->appendTextChild(_("mimetype"), _(DESC_ICON_PNG_MIMETYPE));
00253 icon120_png->appendTextChild(_("width"), _("120"));
00254 icon120_png->appendTextChild(_("height"), _("120"));
00255 icon120_png->appendTextChild(_("depth"), _("24"));
00256 icon120_png->appendTextChild(_("url"), _(DESC_ICON120_PNG));
00257 iconList->appendElementChild(icon120_png);
00258
00259 Ref<Element> icon120_bmp(new Element(_("icon")));
00260 icon120_bmp->appendTextChild(_("mimetype"), _(DESC_ICON_BMP_MIMETYPE));
00261 icon120_bmp->appendTextChild(_("width"), _("120"));
00262 icon120_bmp->appendTextChild(_("height"), _("120"));
00263 icon120_bmp->appendTextChild(_("depth"), _("24"));
00264 icon120_bmp->appendTextChild(_("url"), _(DESC_ICON120_BMP));
00265 iconList->appendElementChild(icon120_bmp);
00266
00267 Ref<Element> icon120_jpg(new Element(_("icon")));
00268 icon120_jpg->appendTextChild(_("mimetype"), _(DESC_ICON_JPG_MIMETYPE));
00269 icon120_jpg->appendTextChild(_("width"), _("120"));
00270 icon120_jpg->appendTextChild(_("height"), _("120"));
00271 icon120_jpg->appendTextChild(_("depth"), _("24"));
00272 icon120_jpg->appendTextChild(_("url"), _(DESC_ICON120_JPG));
00273 iconList->appendElementChild(icon120_jpg);
00274
00275 Ref<Element> icon48_png(new Element(_("icon")));
00276 icon48_png->appendTextChild(_("mimetype"), _(DESC_ICON_PNG_MIMETYPE));
00277 icon48_png->appendTextChild(_("width"), _("48"));
00278 icon48_png->appendTextChild(_("height"), _("48"));
00279 icon48_png->appendTextChild(_("depth"), _("24"));
00280 icon48_png->appendTextChild(_("url"), _(DESC_ICON48_PNG));
00281 iconList->appendElementChild(icon48_png);
00282
00283 Ref<Element> icon48_bmp(new Element(_("icon")));
00284 icon48_bmp->appendTextChild(_("mimetype"), _(DESC_ICON_BMP_MIMETYPE));
00285 icon48_bmp->appendTextChild(_("width"), _("48"));
00286 icon48_bmp->appendTextChild(_("height"), _("48"));
00287 icon48_bmp->appendTextChild(_("depth"), _("24"));
00288 icon48_bmp->appendTextChild(_("url"), _(DESC_ICON48_BMP));
00289 iconList->appendElementChild(icon48_bmp);
00290
00291 Ref<Element> icon48_jpg(new Element(_("icon")));
00292 icon48_jpg->appendTextChild(_("mimetype"), _(DESC_ICON_JPG_MIMETYPE));
00293 icon48_jpg->appendTextChild(_("width"), _("48"));
00294 icon48_jpg->appendTextChild(_("height"), _("48"));
00295 icon48_jpg->appendTextChild(_("depth"), _("24"));
00296 icon48_jpg->appendTextChild(_("url"), _(DESC_ICON48_JPG));
00297 iconList->appendElementChild(icon48_jpg);
00298
00299 Ref<Element> icon32_png(new Element(_("icon")));
00300 icon32_png->appendTextChild(_("mimetype"), _(DESC_ICON_PNG_MIMETYPE));
00301 icon32_png->appendTextChild(_("width"), _("32"));
00302 icon32_png->appendTextChild(_("height"), _("32"));
00303 icon32_png->appendTextChild(_("depth"), _("8"));
00304 icon32_png->appendTextChild(_("url"), _(DESC_ICON32_PNG));
00305 iconList->appendElementChild(icon32_png);
00306
00307 Ref<Element> icon32_bmp(new Element(_("icon")));
00308 icon32_bmp->appendTextChild(_("mimetype"), _(DESC_ICON_BMP_MIMETYPE));
00309 icon32_bmp->appendTextChild(_("width"), _("32"));
00310 icon32_bmp->appendTextChild(_("height"), _("32"));
00311 icon32_bmp->appendTextChild(_("depth"), _("8"));
00312 icon32_bmp->appendTextChild(_("url"), _(DESC_ICON32_BMP));
00313 iconList->appendElementChild(icon32_bmp);
00314
00315 Ref<Element> icon32_jpg(new Element(_("icon")));
00316 icon32_jpg->appendTextChild(_("mimetype"), _(DESC_ICON_JPG_MIMETYPE));
00317 icon32_jpg->appendTextChild(_("width"), _("32"));
00318 icon32_jpg->appendTextChild(_("height"), _("32"));
00319 icon32_jpg->appendTextChild(_("depth"), _("8"));
00320 icon32_jpg->appendTextChild(_("url"), _(DESC_ICON32_JPG));
00321 iconList->appendElementChild(icon32_jpg);
00322
00323 device->appendElementChild(iconList);
00324
00325 Ref<Element> serviceList(new Element(_("serviceList")));
00326
00327 Ref<Element> serviceCM(new Element(_("service")));
00328 serviceCM->appendTextChild(_("serviceType"), _(DESC_CM_SERVICE_TYPE));
00329 serviceCM->appendTextChild(_("serviceId"), _(DESC_CM_SERVICE_ID));
00330 serviceCM->appendTextChild(_("SCPDURL"), _(DESC_CM_SCPD_URL));
00331 serviceCM->appendTextChild(_("controlURL"), _(DESC_CM_CONTROL_URL));
00332 serviceCM->appendTextChild(_("eventSubURL"), _(DESC_CM_EVENT_URL));
00333
00334 serviceList->appendElementChild(serviceCM);
00335
00336 Ref<Element> serviceCDS(new Element(_("service")));
00337 serviceCDS->appendTextChild(_("serviceType"), _(DESC_CDS_SERVICE_TYPE));
00338 serviceCDS->appendTextChild(_("serviceId"), _(DESC_CDS_SERVICE_ID));
00339 serviceCDS->appendTextChild(_("SCPDURL"), _(DESC_CDS_SCPD_URL));
00340 serviceCDS->appendTextChild(_("controlURL"), _(DESC_CDS_CONTROL_URL));
00341 serviceCDS->appendTextChild(_("eventSubURL"), _(DESC_CDS_EVENT_URL));
00342
00343 serviceList->appendElementChild(serviceCDS);
00344
00345 #if defined(ENABLE_MRREG)
00346
00347 Ref<Element> serviceMRREG(new Element(_("service")));
00348 serviceMRREG->appendTextChild(_("serviceType"), _(DESC_MRREG_SERVICE_TYPE));
00349 serviceMRREG->appendTextChild(_("serviceId"), _(DESC_MRREG_SERVICE_ID));
00350 serviceMRREG->appendTextChild(_("SCPDURL"), _(DESC_MRREG_SCPD_URL));
00351 serviceMRREG->appendTextChild(_("controlURL"), _(DESC_MRREG_CONTROL_URL));
00352 serviceMRREG->appendTextChild(_("eventSubURL"), _(DESC_MRREG_EVENT_URL));
00353
00354 serviceList->appendElementChild(serviceMRREG);
00355 #endif
00356
00357 device->appendElementChild(serviceList);
00358
00359 root->appendElementChild(device);
00360
00361 return root;
00362 }
00363
00364 Ref<Element> UpnpXML_DIDLRenderResource(String URL, Ref<Dictionary> attributes)
00365 {
00366 Ref<Element> res(new Element(_("res")));
00367
00368 res->setText(URL);
00369
00370 Ref<Array<DictionaryElement> > elements = attributes->getElements();
00371 int len = elements->size();
00372
00373 String attribute;
00374
00375 for (int i = 0; i < len; i++)
00376 {
00377 Ref<DictionaryElement> el = elements->get(i);
00378 attribute = el->getKey();
00379 res->setAttribute(attribute, el->getValue());
00380 }
00381
00382 return res;
00383 }