1 /* 2 * Copyright 2003-2021 The Music Player Daemon Project 3 * http://www.musicpd.org 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 */ 19 20 #ifndef _UPNPDIR_HXX_INCLUDED_ 21 #define _UPNPDIR_HXX_INCLUDED_ 22 23 #include "Compat.hxx" 24 25 #include <string> 26 #include <forward_list> 27 28 class UPnPDevice; 29 struct UPnPService; 30 class UPnPDirContent; 31 32 /** 33 * Content Directory Service class. 34 * 35 * This stores identity data from a directory service 36 * and the device it belongs to, and has methods to query 37 * the directory, using libupnp for handling the UPnP protocols. 38 * 39 * Note: m_rdreqcnt: number of entries requested per directory read. 40 * 0 means all entries. The device can still return less entries than 41 * requested, depending on its own limits. In general it's not optimal 42 * becauses it triggers issues, and is sometimes actually slower, e.g. on 43 * a D-Link NAS 327 44 * 45 * The value chosen may affect by the UpnpSetMaxContentLength 46 * (2000*1024) done during initialization, but this should be ample 47 */ 48 class ContentDirectoryService { 49 std::string m_actionURL; 50 std::string m_serviceType; 51 std::string m_deviceId; 52 std::string m_friendlyName; 53 std::string m_manufacturer; 54 std::string m_modelName; 55 56 int m_rdreqcnt; // Slice size to use when reading 57 58 public: 59 /** 60 * Construct by copying data from device and service objects. 61 * 62 * The discovery service does this: use 63 * UPnPDeviceDirectory::GetDirectories() 64 */ 65 ContentDirectoryService(const UPnPDevice &device, 66 const UPnPService &service) noexcept; 67 68 /** An empty one */ 69 ContentDirectoryService() = default; 70 71 ~ContentDirectoryService() noexcept; 72 73 /** Read a container's children list into dirbuf. 74 * 75 * @param objectId the UPnP object Id for the container. Root has Id "0" 76 */ 77 UPnPDirContent readDir(UpnpClient_Handle handle, 78 const char *objectId) const; 79 80 void readDirSlice(UpnpClient_Handle handle, 81 const char *objectId, unsigned offset, 82 unsigned count, UPnPDirContent& dirbuf, 83 unsigned &didread, unsigned &total) const; 84 85 /** Search the content directory service. 86 * 87 * @param objectId the UPnP object Id under which the search 88 * should be done. Not all servers actually support this below 89 * root. Root has Id "0" 90 * @param searchstring an UPnP searchcriteria string. Check the 91 * UPnP document: UPnP-av-ContentDirectory-v1-Service-20020625.pdf 92 * section 2.5.5. Maybe we'll provide an easier way some day... 93 */ 94 UPnPDirContent search(UpnpClient_Handle handle, 95 const char *objectId, 96 const char *searchstring) const; 97 98 /** Read metadata for a given node. 99 * 100 * @param objectId the UPnP object Id. Root has Id "0" 101 */ 102 UPnPDirContent getMetadata(UpnpClient_Handle handle, 103 const char *objectId) const; 104 105 /** Retrieve search capabilities 106 * 107 * Throws std::runtime_error on error. 108 * 109 * @param[out] result an empty vector: no search, or a single '*' element: 110 * any tag can be used in a search, or a list of usable tag names. 111 */ 112 std::forward_list<std::string> getSearchCapabilities(UpnpClient_Handle handle) const; 113 114 [[gnu::pure]] GetURI() const115 std::string GetURI() const noexcept { 116 return "upnp://" + m_deviceId + "/" + m_serviceType; 117 } 118 119 /** Retrieve the "friendly name" for this server, useful for display. */ getFriendlyName() const120 const char *getFriendlyName() const noexcept { 121 return m_friendlyName.c_str(); 122 } 123 }; 124 125 #endif /* _UPNPDIR_HXX_INCLUDED_ */ 126