Merge pull request #26220 from 78andyp/blurayfixes
[xbmc.git] / lib / libUPnP / Platinum / Source / Devices / MediaServer / PltMediaServer.cpp
blob8686aa92948d7d467374c7f3521212b9b1cc9e45
1 /*****************************************************************
3 | Platinum - AV Media Server Device
5 | Copyright (c) 2004-2010, Plutinosoft, LLC.
6 | All rights reserved.
7 | http://www.plutinosoft.com
9 | This program is free software; you can redistribute it and/or
10 | modify it under the terms of the GNU General Public License
11 | as published by the Free Software Foundation; either version 2
12 | of the License, or (at your option) any later version.
14 | OEMs, ISVs, VARs and other distributors that combine and
15 | distribute commercially licensed software with Platinum software
16 | and do not wish to distribute the source code for the commercially
17 | licensed software under version 2, or (at your option) any later
18 | version, of the GNU General Public License (the "GPL") must enter
19 | into a commercial license agreement with Plutinosoft, LLC.
20 | licensing@plutinosoft.com
22 | This program is distributed in the hope that it will be useful,
23 | but WITHOUT ANY WARRANTY; without even the implied warranty of
24 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 | GNU General Public License for more details.
27 | You should have received a copy of the GNU General Public License
28 | along with this program; see the file LICENSE.txt. If not, write to
29 | the Free Software Foundation, Inc.,
30 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 | http://www.gnu.org/licenses/gpl-2.0.html
33 ****************************************************************/
35 /*----------------------------------------------------------------------
36 | includes
37 +---------------------------------------------------------------------*/
38 #include "PltUPnP.h"
39 #include "PltMediaServer.h"
40 #include "PltMediaItem.h"
41 #include "PltService.h"
42 #include "PltTaskManager.h"
43 #include "PltHttpServer.h"
44 #include "PltDidl.h"
46 NPT_SET_LOCAL_LOGGER("platinum.media.server")
48 /*----------------------------------------------------------------------
49 | forward references
50 +---------------------------------------------------------------------*/
51 extern NPT_UInt8 MS_ConnectionManagerSCPD[];
52 extern NPT_UInt8 MS_ContentDirectorywSearchSCPD[];
54 const char* BrowseFlagsStr[] = {
55 "BrowseMetadata",
56 "BrowseDirectChildren"
59 /*----------------------------------------------------------------------
60 | PLT_MediaServer::PLT_MediaServer
61 +---------------------------------------------------------------------*/
62 PLT_MediaServer::PLT_MediaServer(const char* friendly_name,
63 bool show_ip /* = false */,
64 const char* uuid /* = NULL */,
65 NPT_UInt16 port /* = 0 */,
66 bool port_rebind /* = false */) :
67 PLT_DeviceHost("/DeviceDescription.xml",
68 uuid,
69 "urn:schemas-upnp-org:device:MediaServer:1",
70 friendly_name,
71 show_ip,
72 port,
73 port_rebind),
74 m_Delegate(NULL)
76 m_ModelDescription = "Plutinosoft AV Media Server Device";
77 m_ModelName = "AV Media Server Device";
78 m_ModelURL = "http://www.plutinosoft.com/platinum";
79 m_DlnaDoc = "DMS-1.50";
82 /*----------------------------------------------------------------------
83 | PLT_MediaServer::~PLT_MediaServer
84 +---------------------------------------------------------------------*/
85 PLT_MediaServer::~PLT_MediaServer()
89 /*----------------------------------------------------------------------
90 | PLT_MediaServer::SetupServices
91 +---------------------------------------------------------------------*/
92 NPT_Result
93 PLT_MediaServer::SetupServices()
95 NPT_Reference<PLT_Service> service;
98 service = new PLT_Service(
99 this,
100 "urn:schemas-upnp-org:service:ContentDirectory:1",
101 "urn:upnp-org:serviceId:ContentDirectory",
102 "ContentDirectory");
103 NPT_CHECK_FATAL(service->SetSCPDXML((const char*) MS_ContentDirectorywSearchSCPD));
104 NPT_CHECK_FATAL(AddService(service.AsPointer()));
106 service->SetStateVariable("ContainerUpdateIDs", "");
107 service->SetStateVariableRate("ContainerUpdateIDs", NPT_TimeInterval(2.));
108 service->SetStateVariable("SystemUpdateID", "0");
109 service->SetStateVariableRate("SystemUpdateID", NPT_TimeInterval(2.));
110 service->SetStateVariable("SearchCapability", "@id,@refID,dc:title,upnp:class,upnp:genre,upnp:artist,upnp:author,upnp:author@role,upnp:album,dc:creator,res@size,res@duration,res@protocolInfo,res@protection,dc:publisher,dc:language,upnp:originalTrackNumber,dc:date,upnp:producer,upnp:rating,upnp:actor,upnp:director,upnp:toc,dc:description,microsoft:userRatingInStars,microsoft:userEffectiveRatingInStars,microsoft:userRating,microsoft:userEffectiveRating,microsoft:serviceProvider,microsoft:artistAlbumArtist,microsoft:artistPerformer,microsoft:artistConductor,microsoft:authorComposer,microsoft:authorOriginalLyricist,microsoft:authorWriter,upnp:userAnnotation,upnp:channelName,upnp:longDescription,upnp:programTitle");
111 service->SetStateVariable("SortCapability", "dc:title,upnp:genre,upnp:album,dc:creator,res@size,res@duration,res@bitrate,dc:publisher,dc:language,upnp:originalTrackNumber,dc:date,upnp:producer,upnp:rating,upnp:actor,upnp:director,upnp:toc,dc:description,microsoft:year,microsoft:userRatingInStars,microsoft:userEffectiveRatingInStars,microsoft:userRating,microsoft:userEffectiveRating,microsoft:serviceProvider,microsoft:artistAlbumArtist,microsoft:artistPerformer,microsoft:artistConductor,microsoft:authorComposer,microsoft:authorOriginalLyricist,microsoft:authorWriter,microsoft:sourceUrl,upnp:userAnnotation,upnp:channelName,upnp:longDescription,upnp:programTitle");
113 service.Detach();
114 service = NULL;
118 service = new PLT_Service(
119 this,
120 "urn:schemas-upnp-org:service:ConnectionManager:1",
121 "urn:upnp-org:serviceId:ConnectionManager",
122 "ConnectionManager");
123 NPT_CHECK_FATAL(service->SetSCPDXML((const char*) MS_ConnectionManagerSCPD));
124 NPT_CHECK_FATAL(AddService(service.AsPointer()));
126 service->SetStateVariable("CurrentConnectionIDs", "0");
127 service->SetStateVariable("SinkProtocolInfo", "");
128 service->SetStateVariable("SourceProtocolInfo", "http-get:*:*:*");
130 service.Detach();
131 service = NULL;
134 return NPT_SUCCESS;
137 /*----------------------------------------------------------------------
138 | PLT_MediaServer::UpdateSystemUpdateID
139 +---------------------------------------------------------------------*/
140 void
141 PLT_MediaServer::UpdateSystemUpdateID(NPT_UInt32 update)
143 NPT_COMPILER_UNUSED(update);
146 /*----------------------------------------------------------------------
147 | PLT_MediaServer::UpdateContainerUpdateID
148 +---------------------------------------------------------------------*/
149 void PLT_MediaServer::UpdateContainerUpdateID(const char* id, NPT_UInt32 update)
151 NPT_COMPILER_UNUSED(id);
152 NPT_COMPILER_UNUSED(update);
155 /*----------------------------------------------------------------------
156 | PLT_MediaServer::OnAction
157 +---------------------------------------------------------------------*/
158 NPT_Result
159 PLT_MediaServer::OnAction(PLT_ActionReference& action,
160 const PLT_HttpRequestContext& context)
162 /* parse the action name */
163 NPT_String name = action->GetActionDesc().GetName();
165 // ContentDirectory
166 if (name.Compare("Browse", true) == 0) {
167 return OnBrowse(action, context);
169 if (name.Compare("Search", true) == 0) {
170 return OnSearch(action, context);
172 if (name.Compare("UpdateObject", true) == 0) {
173 return OnUpdate(action, context);
175 if (name.Compare("GetSystemUpdateID", true) == 0) {
176 return OnGetSystemUpdateID(action, context);
178 if (name.Compare("GetSortCapabilities", true) == 0) {
179 return OnGetSortCapabilities(action, context);
181 if (name.Compare("GetSearchCapabilities", true) == 0) {
182 return OnGetSearchCapabilities(action, context);
185 // ConnectionMananger
186 if (name.Compare("GetCurrentConnectionIDs", true) == 0) {
187 return OnGetCurrentConnectionIDs(action, context);
189 if (name.Compare("GetProtocolInfo", true) == 0) {
190 return OnGetProtocolInfo(action, context);
192 if (name.Compare("GetCurrentConnectionInfo", true) == 0) {
193 return OnGetCurrentConnectionInfo(action, context);
196 action->SetError(401,"No Such Action.");
197 return NPT_SUCCESS;
200 /*----------------------------------------------------------------------
201 | PLT_FileMediaServer::ProcessHttpGetRequest
202 +---------------------------------------------------------------------*/
203 NPT_Result
204 PLT_MediaServer::ProcessHttpGetRequest(NPT_HttpRequest& request,
205 const NPT_HttpRequestContext& context,
206 NPT_HttpResponse& response)
208 /* Try to handle file request */
209 if (m_Delegate) return m_Delegate->ProcessFileRequest(request, context, response);
211 return NPT_ERROR_NO_SUCH_ITEM;
214 /*----------------------------------------------------------------------
215 | PLT_MediaServer::OnGetCurrentConnectionIDs
216 +---------------------------------------------------------------------*/
217 NPT_Result
218 PLT_MediaServer::OnGetCurrentConnectionIDs(PLT_ActionReference& action,
219 const PLT_HttpRequestContext& context)
221 NPT_COMPILER_UNUSED(context);
223 return action->SetArgumentsOutFromStateVariable();
226 /*----------------------------------------------------------------------
227 | PLT_MediaServer::OnGetProtocolInfo
228 +---------------------------------------------------------------------*/
229 NPT_Result
230 PLT_MediaServer::OnGetProtocolInfo(PLT_ActionReference& action,
231 const PLT_HttpRequestContext& context)
233 NPT_COMPILER_UNUSED(context);
235 return action->SetArgumentsOutFromStateVariable();
238 /*----------------------------------------------------------------------
239 | PLT_MediaServer::OnGetCurrentConnectionInfo
240 +---------------------------------------------------------------------*/
241 NPT_Result
242 PLT_MediaServer::OnGetCurrentConnectionInfo(PLT_ActionReference& action,
243 const PLT_HttpRequestContext& context)
245 NPT_COMPILER_UNUSED(context);
247 if (NPT_FAILED(action->VerifyArgumentValue("ConnectionID", "0"))) {
248 action->SetError(706,"No Such Connection.");
249 return NPT_FAILURE;
252 if (NPT_FAILED(action->SetArgumentValue("RcsID", "-1"))){
253 return NPT_FAILURE;
255 if (NPT_FAILED(action->SetArgumentValue("AVTransportID", "-1"))) {
256 return NPT_FAILURE;
258 if (NPT_FAILED(action->SetArgumentValue("ProtocolInfo", "http-get:*:*:*"))) {
259 return NPT_FAILURE;
261 if (NPT_FAILED(action->SetArgumentValue("PeerConnectionManager", "/"))) {
262 return NPT_FAILURE;
264 if (NPT_FAILED(action->SetArgumentValue("PeerConnectionID", "-1"))) {
265 return NPT_FAILURE;
267 if (NPT_FAILED(action->SetArgumentValue("Direction", "Output"))) {
268 return NPT_FAILURE;
270 if (NPT_FAILED(action->SetArgumentValue("Status", "Unknown"))) {
271 return NPT_FAILURE;
274 return NPT_SUCCESS;
277 /*----------------------------------------------------------------------
278 | PLT_MediaServer::OnGetSortCapabilities
279 +---------------------------------------------------------------------*/
280 NPT_Result
281 PLT_MediaServer::OnGetSortCapabilities(PLT_ActionReference& action,
282 const PLT_HttpRequestContext& context)
284 NPT_COMPILER_UNUSED(context);
286 return action->SetArgumentsOutFromStateVariable();
289 /*----------------------------------------------------------------------
290 | PLT_MediaServer::OnGetSearchCapabilities
291 +---------------------------------------------------------------------*/
292 NPT_Result
293 PLT_MediaServer::OnGetSearchCapabilities(PLT_ActionReference& action,
294 const PLT_HttpRequestContext& context)
296 NPT_COMPILER_UNUSED(context);
298 return action->SetArgumentsOutFromStateVariable();
301 /*----------------------------------------------------------------------
302 | PLT_MediaServer::OnGetSystemUpdateID
303 +---------------------------------------------------------------------*/
304 NPT_Result
305 PLT_MediaServer::OnGetSystemUpdateID(PLT_ActionReference& action,
306 const PLT_HttpRequestContext& context)
308 NPT_COMPILER_UNUSED(context);
310 return action->SetArgumentsOutFromStateVariable();
313 /*----------------------------------------------------------------------
314 | PLT_MediaServer::ParseBrowseFlag
315 +---------------------------------------------------------------------*/
316 NPT_Result
317 PLT_MediaServer::ParseBrowseFlag(const char* str, BrowseFlags& flag)
319 if (NPT_String::Compare(str, BrowseFlagsStr[0], true) == 0) {
320 flag = BROWSEMETADATA;
321 return NPT_SUCCESS;
323 if (NPT_String::Compare(str, BrowseFlagsStr[1], true) == 0) {
324 flag = BROWSEDIRECTCHILDREN;
325 return NPT_SUCCESS;
327 return NPT_FAILURE;
330 /*----------------------------------------------------------------------
331 | PLT_MediaServer::ParseSort
332 +---------------------------------------------------------------------*/
333 NPT_Result
334 PLT_MediaServer::ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list)
336 // reset output params first
337 list.Clear();
339 // easy out
340 if (sort.GetLength() == 0 || sort == "*") return NPT_SUCCESS;
342 list = sort.Split(",");
344 // verify each property has a namespace
345 NPT_List<NPT_String>::Iterator property = list.GetFirstItem();
346 while (property) {
347 NPT_List<NPT_String> parsed_property = (*property).Split(":");
348 if (parsed_property.GetItemCount() != 2)
349 parsed_property = (*property).Split("@");
350 if (parsed_property.GetItemCount() != 2 ||
351 (!(*property).StartsWith("-") && !(*property).StartsWith("+"))) {
352 NPT_LOG_WARNING_1("Invalid SortCriteria property %s", (*property).GetChars());
353 return NPT_FAILURE;
355 property++;
358 return NPT_SUCCESS;
361 /*----------------------------------------------------------------------
362 | PLT_MediaServer::ParseTagList
363 +---------------------------------------------------------------------*/
364 NPT_Result
365 PLT_MediaServer::ParseTagList(const NPT_String& updates, NPT_Map<NPT_String,NPT_String>& tags)
367 // reset output params first
368 tags.Clear();
370 NPT_List<NPT_String> split = updates.Split(",");
371 NPT_XmlNode* node = NULL;
372 NPT_XmlElementNode* didl_partial = NULL;
373 NPT_XmlParser parser;
375 // as these are single name value pairs, separated by commas we wrap in a tag
376 // to create a valid tree
377 NPT_String xml("<TagValueList>");
378 for (NPT_List<NPT_String>::Iterator entry = split.GetFirstItem(); entry; entry++) {
379 NPT_String& element = (*entry);
380 if (element.IsEmpty())
381 xml.Append("<empty>empty</empty>");
382 else
383 xml.Append(element);
385 xml.Append("</TagValueList>");
387 NPT_LOG_FINE("Parsing TagList...");
388 NPT_CHECK_LABEL_SEVERE(parser.Parse(xml, node), cleanup);
389 if (!node || !node->AsElementNode()) {
390 NPT_LOG_SEVERE("Invalid node type");
391 goto cleanup;
394 didl_partial = node->AsElementNode();
395 if (didl_partial->GetTag().Compare("TagValueList", true)) {
396 NPT_LOG_SEVERE("Invalid node tag");
397 goto cleanup;
400 for (NPT_List<NPT_XmlNode*>::Iterator children = didl_partial->GetChildren().GetFirstItem(); children; children++) {
401 NPT_XmlElementNode* child = (*children)->AsElementNode();
402 if (!child) continue;
403 const NPT_String *txt = child->GetText();
404 tags[child->GetTag()] = txt ? txt->GetChars() : "";
407 return NPT_SUCCESS;
409 cleanup:
410 if (node) delete node;
411 return NPT_FAILURE;
415 /*----------------------------------------------------------------------
416 | PLT_MediaServer::OnBrowse
417 +---------------------------------------------------------------------*/
418 NPT_Result
419 PLT_MediaServer::OnBrowse(PLT_ActionReference& action,
420 const PLT_HttpRequestContext& context)
422 NPT_Result res;
423 NPT_String object_id;
424 NPT_String browse_flag_val;
425 NPT_String filter;
426 NPT_String start;
427 NPT_String count;
428 NPT_String sort;
429 NPT_List<NPT_String> sort_list;
431 if (NPT_FAILED(action->GetArgumentValue("ObjectId", object_id)) ||
432 NPT_FAILED(action->GetArgumentValue("BrowseFlag", browse_flag_val)) ||
433 NPT_FAILED(action->GetArgumentValue("Filter", filter)) ||
434 NPT_FAILED(action->GetArgumentValue("StartingIndex", start)) ||
435 NPT_FAILED(action->GetArgumentValue("RequestedCount", count)) ||
436 NPT_FAILED(action->GetArgumentValue("SortCriteria", sort))) {
437 NPT_LOG_WARNING("Missing arguments");
438 action->SetError(402, "Invalid args");
439 return NPT_SUCCESS;
442 /* extract flag */
443 BrowseFlags flag;
444 if (NPT_FAILED(ParseBrowseFlag(browse_flag_val, flag))) {
445 /* error */
446 NPT_LOG_WARNING_1("BrowseFlag value not allowed (%s)", (const char*)browse_flag_val);
447 action->SetError(402, "Invalid args");
448 return NPT_SUCCESS;
451 /* convert index and counts to int */
452 NPT_UInt32 starting_index, requested_count;
453 if (NPT_FAILED(start.ToInteger(starting_index)) ||
454 NPT_FAILED(count.ToInteger(requested_count)) ||
455 PLT_Didl::ConvertFilterToMask(filter) == 0) {
456 NPT_LOG_WARNING_3("Invalid arguments (%s, %s, %s)",
457 start.GetChars(), count.GetChars(), filter.GetChars());
458 action->SetError(402, "Invalid args");
459 return NPT_FAILURE;
462 /* parse sort criteria for validation */
463 if (NPT_FAILED(ParseSort(sort, sort_list))) {
464 NPT_LOG_WARNING_1("Unsupported or invalid sort criteria error (%s)",
465 sort.GetChars());
466 action->SetError(709, "Unsupported or invalid sort criteria error");
467 return NPT_FAILURE;
470 NPT_LOG_FINE_6("Processing %s from %s with id=\"%s\", filter=\"%s\", start=%d, count=%d",
471 (const char*)browse_flag_val,
472 (const char*)context.GetRemoteAddress().GetIpAddress().ToString(),
473 (const char*)object_id,
474 (const char*)filter,
475 starting_index,
476 requested_count);
478 /* Invoke the browse function */
479 if (flag == BROWSEMETADATA) {
480 res = OnBrowseMetadata(
481 action,
482 object_id,
483 filter,
484 starting_index,
485 requested_count,
486 sort,
487 context);
488 } else {
489 res = OnBrowseDirectChildren(
490 action,
491 object_id,
492 filter,
493 starting_index,
494 requested_count,
495 sort,
496 context);
499 if (NPT_FAILED(res) && (action->GetErrorCode() == 0)) {
500 action->SetError(800, "Internal error");
503 return res;
506 /*----------------------------------------------------------------------
507 | PLT_MediaServer::OnSearch
508 +---------------------------------------------------------------------*/
509 NPT_Result
510 PLT_MediaServer::OnSearch(PLT_ActionReference& action,
511 const PLT_HttpRequestContext& context)
513 NPT_COMPILER_UNUSED(context);
515 NPT_Result res;
516 NPT_String container_id;
517 NPT_String search;
518 NPT_String filter;
519 NPT_String start;
520 NPT_String count;
521 NPT_String sort;
522 NPT_List<NPT_String> sort_list;
524 if (NPT_FAILED(action->GetArgumentValue("ContainerId", container_id)) ||
525 NPT_FAILED(action->GetArgumentValue("SearchCriteria", search)) ||
526 NPT_FAILED(action->GetArgumentValue("Filter", filter)) ||
527 NPT_FAILED(action->GetArgumentValue("StartingIndex", start)) ||
528 NPT_FAILED(action->GetArgumentValue("RequestedCount", count)) ||
529 NPT_FAILED(action->GetArgumentValue("SortCriteria", sort))) {
530 NPT_LOG_WARNING("Missing arguments");
531 action->SetError(402, "Invalid args");
532 return NPT_SUCCESS;
535 /* convert index and counts to int */
536 NPT_UInt32 starting_index, requested_count;
537 if (NPT_FAILED(start.ToInteger(starting_index)) ||
538 NPT_FAILED(count.ToInteger(requested_count))) {
539 NPT_LOG_WARNING_2("Invalid arguments (%s, %s)",
540 start.GetChars(), count.GetChars());
541 action->SetError(402, "Invalid args");
542 return NPT_FAILURE;
545 /* parse sort criteria */
546 if (NPT_FAILED(ParseSort(sort, sort_list))) {
547 NPT_LOG_WARNING_1("Unsupported or invalid sort criteria error (%s)",
548 sort.GetChars());
549 action->SetError(709, "Unsupported or invalid sort criteria error");
550 return NPT_FAILURE;
553 NPT_LOG_INFO_5("Processing Search from %s with id=\"%s\", search=\"%s\", start=%d, count=%d",
554 (const char*)context.GetRemoteAddress().GetIpAddress().ToString(),
555 (const char*)container_id,
556 (const char*)search,
557 starting_index,
558 requested_count);
560 if (search.IsEmpty() || search == "*") {
561 res = OnBrowseDirectChildren(
562 action,
563 container_id,
564 filter,
565 starting_index,
566 requested_count,
567 sort,
568 context);
569 } else {
570 res = OnSearchContainer(
571 action,
572 container_id,
573 search,
574 filter,
575 starting_index,
576 requested_count,
577 sort,
578 context);
581 if (NPT_FAILED(res) && (action->GetErrorCode() == 0)) {
582 action->SetError(800, "Internal error");
585 return res;
588 /*----------------------------------------------------------------------
589 | PLT_MediaServer::OnUpdate
590 +---------------------------------------------------------------------*/
591 NPT_Result
592 PLT_MediaServer::OnUpdate(PLT_ActionReference& action,
593 const PLT_HttpRequestContext& context)
595 if (!m_Delegate)
596 return NPT_ERROR_NOT_IMPLEMENTED;
598 int err;
599 const char* msg = NULL;
601 NPT_String object_id, current_xml, new_xml;
602 NPT_Map<NPT_String,NPT_String> curr_values;
603 NPT_Map<NPT_String,NPT_String> new_values;
605 NPT_CHECK_LABEL(action->GetArgumentValue("ObjectID", object_id), args);
606 NPT_CHECK_LABEL(object_id.IsEmpty(),args);
607 NPT_CHECK_LABEL(action->GetArgumentValue("CurrentTagValue", current_xml), args);
608 NPT_CHECK_LABEL(action->GetArgumentValue("NewTagValue", new_xml), args);
610 if (NPT_FAILED(ParseTagList(current_xml, curr_values))) {
611 err = 702;
612 msg = "Invalid currentTagvalue";
613 goto failure;
615 if (NPT_FAILED(ParseTagList(new_xml, new_values))) {
616 err = 703;
617 msg = "Invalid newTagValue";
618 goto failure;
621 if (curr_values.GetEntryCount() != new_values.GetEntryCount()) {
622 err = 706;
623 msg = "Paramater mismatch";
624 goto failure;
627 return m_Delegate->OnUpdateObject(action, object_id, curr_values, new_values, context);
629 args:
630 err = 402;
631 msg = "Invalid args";
633 failure:
634 NPT_LOG_WARNING_1("%s", msg);
635 action->SetError(err, msg);
636 return NPT_FAILURE;
639 /*----------------------------------------------------------------------
640 | PLT_MediaServer::OnBrowseMetadata
641 +---------------------------------------------------------------------*/
642 NPT_Result
643 PLT_MediaServer::OnBrowseMetadata(PLT_ActionReference& action,
644 const char* object_id,
645 const char* filter,
646 NPT_UInt32 starting_index,
647 NPT_UInt32 requested_count,
648 const char* sort_criteria,
649 const PLT_HttpRequestContext& context)
651 if (m_Delegate) {
652 return m_Delegate->OnBrowseMetadata(action,
653 object_id,
654 filter,
655 starting_index,
656 requested_count,
657 sort_criteria,
658 context);
660 return NPT_ERROR_NOT_IMPLEMENTED;
663 /*----------------------------------------------------------------------
664 | PLT_MediaServer::OnBrowseDirectChildren
665 +---------------------------------------------------------------------*/
666 NPT_Result
667 PLT_MediaServer::OnBrowseDirectChildren(PLT_ActionReference& action,
668 const char* object_id,
669 const char* filter,
670 NPT_UInt32 starting_index,
671 NPT_UInt32 requested_count,
672 const char* sort_criteria,
673 const PLT_HttpRequestContext& context)
675 if (m_Delegate) {
676 return m_Delegate->OnBrowseDirectChildren(action,
677 object_id,
678 filter,
679 starting_index,
680 requested_count,
681 sort_criteria,
682 context);
684 return NPT_ERROR_NOT_IMPLEMENTED;
687 /*----------------------------------------------------------------------
688 | PLT_MediaServer::OnSearchContainer
689 +---------------------------------------------------------------------*/
690 NPT_Result
691 PLT_MediaServer::OnSearchContainer(PLT_ActionReference& action,
692 const char* object_id,
693 const char* search_criteria,
694 const char* filter,
695 NPT_UInt32 starting_index,
696 NPT_UInt32 requested_count,
697 const char* sort_criteria,
698 const PLT_HttpRequestContext& context)
700 if (m_Delegate) {
701 return m_Delegate->OnSearchContainer(action,
702 object_id,
703 search_criteria,
704 filter,
705 starting_index,
706 requested_count,
707 sort_criteria,
708 context);
710 return NPT_ERROR_NOT_IMPLEMENTED;