Arduino DLNA Server
Loading...
Searching...
No Matches
DLNADeviceInfo.h
Go to the documentation of this file.
1
2#pragma once
3
4#include "basic/Icon.h"
5#include "basic/Vector.h"
6#include "dlna/Action.h"
8#include "dlna/udp/IUDPService.h" // Ensure IUDPService is declared
11
12namespace tiny_dlna {
13
26 friend class XMLDeviceParser;
27 friend class DLNAControlPoint;
28 template <typename>
29 friend class DLNADevice;
30
31 public:
32 DLNADeviceInfo(bool ok = true) { is_active = ok; }
33
34 // Explicitly define copy constructor as const (needed for std::vector)
36 : is_active(other.is_active),
39 base_url(other.base_url),
40 udn(other.udn),
47 model_url(other.model_url),
51 icon(other.icon),
52 services(other.services),
53 icons(other.icons),
55
56 ~DLNADeviceInfo() { DlnaLogger.log(DlnaLogLevel::Debug, "~DLNADevice()"); }
57
59 virtual bool begin() { return true; }
60
66 size_t print(Print& out, void* ref = nullptr) {
67 XMLPrinter xp(out);
68 size_t result = 0;
69 result += xp.printXMLHeader();
70 result += xp.printNode(
71 "root",
72 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
73 return ((DLNADeviceInfo*)r)->printRoot(o, r);
74 }),
75 this, ns);
76 return result;
77 }
78
79 // sets the device type (ST or NT)
80 void setDeviceType(const char* st) { device_type = st; }
81
82 const char* getDeviceType() { return device_type.c_str(); }
83
85 void setUDN(const char* id) { udn = id; }
86
88 const char* getUDN() { return udn.c_str(); }
89
91 void setBaseURL(const char* url) {
92 DlnaLogger.log(DlnaLogLevel::Info, "Base URL: %s", url);
93 base_url = url;
94 }
95
97 void setBaseURL(IPAddress ip, int port, const char* path = nullptr) {
98 localhost = ip;
99 Str str{80};
100 str = "http://";
101 str += ip[0];
102 str += ".";
103 str += ip[1];
104 str += ".";
105 str += ip[2];
106 str += ".";
107 str += ip[3];
108 str += ":";
109 str += port;
110 if (path != nullptr && !StrView(path).startsWith("/")) {
111 str += "/";
112 }
113 str += path;
114 setBaseURL(str.c_str());
115 }
116
118 const char* getBaseURL() {
119 // replace localhost url
120 if (StrView(base_url).contains("localhost")) {
122 url_str.replace("localhost", getIPStr());
124 }
125 return base_url.c_str();
126 }
127
130 if (!device_url) {
131 Str str = getBaseURL();
132 if (!str.endsWith("/")) str += "/";
133 str += "device.xml";
134 Url new_url(str.c_str());
135 device_url = new_url;
136 }
137 return device_url;
138 }
139
141 void setIPAddress(IPAddress address) { localhost = address; }
142
144 IPAddress getIPAddress() { return localhost; }
145
147 const char* getIPStr() {
148 static char result[80] = {0};
149 snprintf(result, 80, "%d.%d.%d.%d", localhost[0], localhost[1],
150 localhost[2], localhost[3]);
151 return result;
152 }
153
154 void setNS(const char* ns) { this->ns = ns; }
155 const char* getNS() { return ns.c_str(); }
156 void setFriendlyName(const char* name) { friendly_name = name; }
157 const char* getFriendlyName() { return friendly_name.c_str(); }
158 void setManufacturer(const char* man) { manufacturer = man; }
159 const char* getManufacturer() { return manufacturer.c_str(); }
160 void setManufacturerURL(const char* url) { manufacturer_url = url; }
161 const char* getManufacturerURL() { return manufacturer_url.c_str(); }
162 void setModelDescription(const char* descr) { model_description = descr; }
163 const char* getModelDescription() { return model_description.c_str(); }
164 void setModelName(const char* name) { model_name = name; }
165 const char* getModelName() { return model_name.c_str(); }
166 void setModelNumber(const char* number) { model_number = number; }
167 const char* getModelNumber() { return model_number.c_str(); }
168 void setSerialNumber(const char* sn) { serial_number = sn; }
169 const char* getSerialNumber() { return serial_number.c_str(); }
170 void setUniversalProductCode(const char* upc) {
172 }
175 }
176
178 void addService(DLNAServiceInfo s) { services.push_back(s); }
179
181 DLNAServiceInfo& getService(const char* id) {
182 static DLNAServiceInfo result{false};
183 for (auto& service : services) {
184 if (StrView(service.service_id).contains(id)) {
185 return service;
186 }
187 }
188 return result;
189 }
191 DLNAServiceInfo& getServiceByAbbrev(const char* abbrev) {
192 static DLNAServiceInfo result{false};
193 if (services.empty()) return result;
194 for (auto& service : services) {
195 if (StrView(service.subscription_namespace_abbrev).equals(abbrev)) {
196 return service;
197 }
198 }
199 return result;
200 }
201
204
206 void clear() {
207 services.clear();
208 udn = "";
209 ns = "";
210 device_type = "";
211 friendly_name = "";
212 manufacturer = "";
213 manufacturer_url = "";
215 model_name = "";
216 model_number = "";
217 serial_number = "";
219 }
220
222 void clearIcons() { icons.clear(); }
223
225 void addIcon(Icon icon) { icons.push_back(icon); }
226
228 Icon getIcon(int idx = 0) {
229 if (icons.size() == 0) {
230 Icon empty;
231 return empty;
232 }
233 return icons[idx];
234 }
235
237 void setActive(bool flag) { is_active = flag; }
238
240 operator bool() { return is_active; }
241
243 virtual bool loop() {
244 delay(1);
245 return true;
246 }
247
249
251
252 protected:
253 bool is_active = false;
255 IPAddress localhost;
258 Str base_url = "http://localhost:9876/dlna";
259 Str udn = "uuid:09349455-2941-4cf7-9847-0dd5ab210e97";
260 Str ns = "xmlns=\"urn:schemas-upnp-org:device-1-0\"";
276
278 virtual void setupServices(IHttpServer& server, IUDPService& udp) {}
279
280 size_t printRoot(Print& out, void* ref) {
281 XMLPrinter xp(out);
282 size_t result = 0;
283 result += xp.printNode(
284 "specVersion",
285 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
286 return ((DLNADeviceInfo*)r)->printSpecVersion(o, r);
287 }),
288 this);
289 result += xp.printNode("URLBase", base_url);
290 result += xp.printNode(
291 "device",
292 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
293 return ((DLNADeviceInfo*)r)->printDevice(o, r);
294 }),
295 this);
296 return result;
297 }
298
299 size_t printDevice(Print& out, void* ref) {
300 XMLPrinter xp(out);
301 size_t result = 0;
302 result += xp.printNode("deviceType", getDeviceType());
303 result += xp.printNode("friendlyName", friendly_name);
304 result += xp.printNode("manufacturer", manufacturer);
305 result += xp.printNode("manufacturerURL", manufacturer_url);
306 result += xp.printNode("modelDescription", model_description);
307 result += xp.printNode("modelName", model_name);
308 result += xp.printNode("modelNumber", model_number);
309 result += xp.printNode("modelURL", model_url);
310 result += xp.printNode("serialNumber", serial_number);
311 result += xp.printNode("UDN", getUDN());
312 result += xp.printNode("UPC", universal_product_code);
313 // use ref-based callbacks that receive Print& and void*
314 result += xp.printNode(
315 "iconList",
316 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
317 return ((DLNADeviceInfo*)r)->printIconList(o, r);
318 }),
319 this);
320 result += xp.printNode(
321 "serviceList",
322 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
323 return ((DLNADeviceInfo*)r)->printServiceList(o, r);
324 }),
325 this);
326 return result;
327 }
328
329 size_t printSpecVersion(Print& out, void* ref) {
330 XMLPrinter xp(out);
331 char major[5], minor[5];
332 sprintf(major, "%d", this->version_major);
333 sprintf(minor, "%d", this->version_minor);
334 return xp.printNode("major", major) + xp.printNode("minor", minor);
335 }
336
337 size_t printServiceList(Print& out, void* ref) {
338 XMLPrinter xp(out);
339 size_t result = 0;
340 for (auto& service : services) {
341 struct Ctx {
342 DLNADeviceInfo* self;
343 DLNAServiceInfo* svc;
344 } ctx{this, &service};
345 result += xp.printNode(
346 "service",
347 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
348 Ctx* c = (Ctx*)r;
349 return c->self->printService(o, c->svc);
350 }),
351 &ctx);
352 }
353 return result;
354 }
355
356 size_t printService(Print& out, void* srv) {
357 XMLPrinter xp(out);
358 size_t result = 0;
359 char buffer[DLNA_MAX_URL_LEN] = {0};
360 StrView url(buffer, DLNA_MAX_URL_LEN);
361 DLNAServiceInfo* service = (DLNAServiceInfo*)srv;
362 result += xp.printNode("serviceType", service->service_type);
363 result += xp.printNode("serviceId", service->service_id);
364 result +=
365 xp.printNode("SCPDURL", url.buildPath(base_url, service->scpd_url));
366 result += xp.printNode("controlURL",
367 url.buildPath(base_url, service->control_url));
369 result += xp.printNode("eventSubURL",
370 url.buildPath(base_url, service->event_sub_url));
371 else
372 result += xp.printf("<eventSubURL/>");
373
374 return result;
375 }
376
377 size_t printIconList(Print& out, void* ref) {
378 // make sure we have at least the default icon
379 Icon icon;
380 if (icons.empty()) {
381 icons.push_back(icon);
382 }
383 XMLPrinter xp(out);
384 int result = 0;
385
386 // print all icons
387 for (auto& icon : icons) {
388 struct CtxI {
389 DLNADeviceInfo* self;
390 Icon* icon;
391 } ctx{this, &icon};
392 result += xp.printNode(
393 "icon",
394 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
395 CtxI* c = (CtxI*)r;
396 return c->self->printIconDlnaInfo(o, c->icon);
397 }),
398 &ctx);
399 }
400 return result;
401 }
402
403 size_t printIconDlnaInfo(Print& out, Icon* icon) {
404 XMLPrinter xp(out);
405 size_t result = 0;
406 if (!StrView(icon->icon_url).isEmpty()) {
407 char buffer[DLNA_MAX_URL_LEN] = {0};
408 StrView url(buffer, DLNA_MAX_URL_LEN);
409 result += xp.printNode("mimetype", "image/png");
410 result += xp.printNode("width", icon->width);
411 result += xp.printNode("height", icon->height);
412 result += xp.printNode("depth", icon->depth);
413 result += xp.printNode("url", url.buildPath(base_url, icon->icon_url));
414 }
415 return result;
416 }
417};
418
419} // namespace tiny_dlna
Lightweight DLNA control point manager.
Definition: DLNAControlPoint.h:61
Device Attributes and generation of XML using urn:schemas-upnp-org:device-1-0. We could just return a...
Definition: DLNADeviceInfo.h:25
Vector< DLNAServiceInfo > & getServices()
Provides all service definitions.
Definition: DLNADeviceInfo.h:203
Str udn
Definition: DLNADeviceInfo.h:259
Vector< DLNAServiceInfo > services
Definition: DLNADeviceInfo.h:272
Url device_url
Definition: DLNADeviceInfo.h:254
void setModelDescription(const char *descr)
Definition: DLNADeviceInfo.h:162
Str model_number
Definition: DLNADeviceInfo.h:268
size_t printSpecVersion(Print &out, void *ref)
Definition: DLNADeviceInfo.h:329
int version_minor
Definition: DLNADeviceInfo.h:257
Str device_type
Definition: DLNADeviceInfo.h:261
IPAddress localhost
Definition: DLNADeviceInfo.h:255
~DLNADeviceInfo()
Definition: DLNADeviceInfo.h:56
void setDeviceType(const char *st)
Definition: DLNADeviceInfo.h:80
Icon icon
Definition: DLNADeviceInfo.h:271
Str universal_product_code
Definition: DLNADeviceInfo.h:270
const char * getFriendlyName()
Definition: DLNADeviceInfo.h:157
void addService(DLNAServiceInfo s)
Adds a service definition.
Definition: DLNADeviceInfo.h:178
Str manufacturer_url
Definition: DLNADeviceInfo.h:264
Icon getIcon(int idx=0)
Provides the item at indix.
Definition: DLNADeviceInfo.h:228
void setNS(const char *ns)
Definition: DLNADeviceInfo.h:154
const char * getManufacturer()
Definition: DLNADeviceInfo.h:159
void addIcon(Icon icon)
adds an icon
Definition: DLNADeviceInfo.h:225
size_t printRoot(Print &out, void *ref)
Definition: DLNADeviceInfo.h:280
void setManufacturerURL(const char *url)
Definition: DLNADeviceInfo.h:160
DLNAServiceInfo & getService(const char *id)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:181
Str url_str
Definition: DLNADeviceInfo.h:274
void clear()
Clears all device information.
Definition: DLNADeviceInfo.h:206
Str ns
Definition: DLNADeviceInfo.h:260
size_t print(Print &out, void *ref=nullptr)
renders the device xml into the provided Print output.
Definition: DLNADeviceInfo.h:66
size_t printService(Print &out, void *srv)
Definition: DLNADeviceInfo.h:356
void clearIcons()
Overwrite the default icon.
Definition: DLNADeviceInfo.h:222
Str base_url
Definition: DLNADeviceInfo.h:258
DLNADeviceInfo(const DLNADeviceInfo &other)
Definition: DLNADeviceInfo.h:35
void setSubscriptionActive(bool flag)
Definition: DLNADeviceInfo.h:248
Str model_name
Definition: DLNADeviceInfo.h:266
const char * getUDN()
Provide the udn uuid.
Definition: DLNADeviceInfo.h:88
const char * getUniversalProductCode()
Definition: DLNADeviceInfo.h:173
void setModelName(const char *name)
Definition: DLNADeviceInfo.h:164
const char * getNS()
Definition: DLNADeviceInfo.h:155
void setSerialNumber(const char *sn)
Definition: DLNADeviceInfo.h:168
const char * getBaseURL()
Provides the base url.
Definition: DLNADeviceInfo.h:118
bool is_subcription_active
Definition: DLNADeviceInfo.h:275
virtual bool begin()
Override to initialize the device.
Definition: DLNADeviceInfo.h:59
const char * getModelDescription()
Definition: DLNADeviceInfo.h:163
Url & getDeviceURL()
This method returns base url/device.xml.
Definition: DLNADeviceInfo.h:129
void setManufacturer(const char *man)
Definition: DLNADeviceInfo.h:158
virtual void setupServices(IHttpServer &server, IUDPService &udp)
to be implemented by subclasses
Definition: DLNADeviceInfo.h:278
Str manufacturer
Definition: DLNADeviceInfo.h:263
void setUDN(const char *id)
Define the udn uuid.
Definition: DLNADeviceInfo.h:85
void setFriendlyName(const char *name)
Definition: DLNADeviceInfo.h:156
IPAddress getIPAddress()
Provides the local IP address.
Definition: DLNADeviceInfo.h:144
Str model_description
Definition: DLNADeviceInfo.h:265
void setActive(bool flag)
Sets the server to inactive.
Definition: DLNADeviceInfo.h:237
bool isSubscriptionActive()
Definition: DLNADeviceInfo.h:250
size_t printIconList(Print &out, void *ref)
Definition: DLNADeviceInfo.h:377
Str serial_number
Definition: DLNADeviceInfo.h:269
DLNADeviceInfo(bool ok=true)
Definition: DLNADeviceInfo.h:32
const char * getModelNumber()
Definition: DLNADeviceInfo.h:167
void setIPAddress(IPAddress address)
Defines the local IP address.
Definition: DLNADeviceInfo.h:141
const char * getSerialNumber()
Definition: DLNADeviceInfo.h:169
virtual bool loop()
loop processing
Definition: DLNADeviceInfo.h:243
const char * getModelName()
Definition: DLNADeviceInfo.h:165
void setBaseURL(IPAddress ip, int port, const char *path=nullptr)
Defines the base URL.
Definition: DLNADeviceInfo.h:97
Vector< Icon > icons
Definition: DLNADeviceInfo.h:273
DLNAServiceInfo & getServiceByAbbrev(const char *abbrev)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:191
const char * getManufacturerURL()
Definition: DLNADeviceInfo.h:161
size_t printServiceList(Print &out, void *ref)
Definition: DLNADeviceInfo.h:337
Str model_url
Definition: DLNADeviceInfo.h:267
bool is_active
Definition: DLNADeviceInfo.h:253
Str friendly_name
Definition: DLNADeviceInfo.h:262
size_t printDevice(Print &out, void *ref)
Definition: DLNADeviceInfo.h:299
void setModelNumber(const char *number)
Definition: DLNADeviceInfo.h:166
void setBaseURL(const char *url)
Defines the base url.
Definition: DLNADeviceInfo.h:91
const char * getDeviceType()
Definition: DLNADeviceInfo.h:82
void setUniversalProductCode(const char *upc)
Definition: DLNADeviceInfo.h:170
size_t printIconDlnaInfo(Print &out, Icon *icon)
Definition: DLNADeviceInfo.h:403
int version_major
Definition: DLNADeviceInfo.h:256
const char * getIPStr()
Provides the local address as string.
Definition: DLNADeviceInfo.h:147
Setup of a Basic DLNA Device service. The device registers itself to the network and answers to the D...
Definition: DLNADevice.h:39
Attributes needed for the DLNA Service Definition.
Definition: DLNAServiceInfo.h:18
Str event_sub_url
Definition: DLNAServiceInfo.h:41
Str service_id
Definition: DLNAServiceInfo.h:38
Str scpd_url
Definition: DLNAServiceInfo.h:39
Str service_type
Definition: DLNAServiceInfo.h:37
Str control_url
Definition: DLNAServiceInfo.h:40
Abstract interface for HTTP server functionality.
Definition: IHttpServer.h:30
Abstract Interface for UDP API.
Definition: IUDPService.h:33
Information about the icon.
Definition: Icon.h:10
const char * icon_url
Definition: Icon.h:16
int width
Definition: Icon.h:13
int height
Definition: Icon.h:14
int depth
Definition: Icon.h:15
A simple wrapper to provide string functions on char*. If the underlying char* is a const we do not a...
Definition: StrView.h:18
virtual bool isEmpty()
checks if the string is empty
Definition: StrView.h:383
const char * buildPath(const char *start, const char *p1=nullptr, const char *p2=nullptr)
Definition: StrView.h:757
virtual bool equals(const char *str)
checks if the string equals indicated parameter string
Definition: StrView.h:177
virtual bool contains(const char *str)
checks if the string contains a substring
Definition: StrView.h:284
Heap-backed string utility used throughout tiny_dlna.
Definition: Str.h:27
bool endsWith(const char *suffix) const
True if ends with suffix (case-sensitive)
Definition: Str.h:175
const char * c_str() const
C-string pointer to internal buffer.
Definition: Str.h:88
bool replace(const char *toReplace, const char *replaced, int startPos=0)
Replace first occurrence of toReplace with replaced starting at startPos.
Definition: Str.h:269
URL parser which breaks a full url string up into its individual parts.
Definition: Url.h:18
Lightweight wrapper around std::vector with Arduino-friendly helpers and a pluggable allocator.
Definition: Vector.h:39
Incremental XML device parser using XMLParserPrint.
Definition: XMLDeviceParser.h:20
#define DLNA_MAX_URL_LEN
app-wide max URL length
Definition: dlna_config.h:45
Definition: Allocator.h:13
Functions to efficiently output XML. XML data contains a lot of redundancy so it is more memory effic...
Definition: XMLPrinter.h:56
size_t printNode(XMLNode node)
Prints an XML node from XMLNode struct.
Definition: XMLPrinter.h:89
size_t printf(const char *fmt,...)
printf-style helper that formats into an internal buffer and writes to the configured Print output.
Definition: XMLPrinter.h:248
size_t printXMLHeader()
Prints the XML header.
Definition: XMLPrinter.h:79