aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/upnp/ContentDirectoryService.hxx
blob: 576c6ec8ceae46f73cfdd0456c44931b9d410a5d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * Copyright (C) 2003-2015 The Music Player Daemon Project
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef _UPNPDIR_HXX_INCLUDED_
#define _UPNPDIR_HXX_INCLUDED_

#include "Compiler.h"

#include <upnp/upnp.h>

#include <string>
#include <list>

class Error;
class UPnPDevice;
struct UPnPService;
class UPnPDirContent;

/**
 * Content Directory Service class.
 *
 * This stores identity data from a directory service
 * and the device it belongs to, and has methods to query
 * the directory, using libupnp for handling the UPnP protocols.
 *
 * Note: m_rdreqcnt: number of entries requested per directory read.
 * 0 means all entries. The device can still return less entries than
 * requested, depending on its own limits. In general it's not optimal
 * becauses it triggers issues, and is sometimes actually slower, e.g. on
 * a D-Link NAS 327
 *
 * The value chosen may affect by the UpnpSetMaxContentLength
 * (2000*1024) done during initialization, but this should be ample
 */
class ContentDirectoryService {
	std::string m_actionURL;
	std::string m_serviceType;
	std::string m_deviceId;
	std::string m_friendlyName;
	std::string m_manufacturer;
	std::string m_modelName;

	int m_rdreqcnt; // Slice size to use when reading

public:
	/**
	 * Construct by copying data from device and service objects.
	 *
	 * The discovery service does this: use getDirServices()
	 */
	ContentDirectoryService(const UPnPDevice &device,
				const UPnPService &service);

	/** An empty one */
	ContentDirectoryService() = default;

	~ContentDirectoryService();

	/** Read a container's children list into dirbuf.
	 *
	 * @param objectId the UPnP object Id for the container. Root has Id "0"
	 * @param[out] dirbuf stores the entries we read.
	 */
	bool readDir(UpnpClient_Handle handle,
		     const char *objectId, UPnPDirContent &dirbuf,
		     Error &error) const;

	bool readDirSlice(UpnpClient_Handle handle,
			  const char *objectId, unsigned offset,
			  unsigned count, UPnPDirContent& dirbuf,
			  unsigned &didread, unsigned &total,
			  Error &error) const;

	/** Search the content directory service.
	 *
	 * @param objectId the UPnP object Id under which the search
	 * should be done. Not all servers actually support this below
	 * root. Root has Id "0"
	 * @param searchstring an UPnP searchcriteria string. Check the
	 * UPnP document: UPnP-av-ContentDirectory-v1-Service-20020625.pdf
	 * section 2.5.5. Maybe we'll provide an easier way some day...
	 * @param[out] dirbuf stores the entries we read.
	 */
	bool search(UpnpClient_Handle handle,
		    const char *objectId, const char *searchstring,
		    UPnPDirContent &dirbuf,
		    Error &error) const;

	/** Read metadata for a given node.
	 *
	 * @param objectId the UPnP object Id. Root has Id "0"
	 * @param[out] dirbuf stores the entries we read. At most one entry will be
	 *   returned.
	 */
	bool getMetadata(UpnpClient_Handle handle,
			 const char *objectId, UPnPDirContent &dirbuf,
			 Error &error) const;

	/** Retrieve search capabilities
	 *
	 * @param[out] result an empty vector: no search, or a single '*' element:
	 *     any tag can be used in a search, or a list of usable tag names.
	 */
	bool getSearchCapabilities(UpnpClient_Handle handle,
				   std::list<std::string> &result,
				   Error &error) const;

	gcc_pure
	std::string GetURI() const {
		return "upnp://" + m_deviceId + "/" + m_serviceType;
	}

	/** Retrieve the "friendly name" for this server, useful for display. */
	const char *getFriendlyName() const {
		return m_friendlyName.c_str();
	}
};

#endif /* _UPNPDIR_HXX_INCLUDED_ */