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"
8#include "dlna/udp/IUDPService.h" // Ensure IUDPService is declared
11#include "icons/icon128x128.h"
12#include "icons/icon48x48.h"
13#include "icons/icon512x512.h"
14
15namespace tiny_dlna {
16
29 friend class XMLDeviceParser;
30 friend class DLNAControlPoint;
31 template <typename>
32 friend class DLNADevice;
33
34 public:
35 DLNADeviceInfo(bool ok = true) { is_active = ok; }
36
37 // Explicitly define copy constructor as const (needed for std::vector)
39 : is_active(other.is_active),
42 base_url(other.base_url),
43 udn(other.udn),
44 ns(other.ns),
45 x_dlnacap(other.x_dlnacap),
52 model_url(other.model_url),
56 services(other.services),
57 icons(other.icons),
59
60 ~DLNADeviceInfo() { DlnaLogger.log(DlnaLogLevel::Debug, "~DLNADevice()"); }
61
63 virtual bool begin() { return true; }
64
70 size_t print(Print& out, void* ref = nullptr) {
71 XMLPrinter xp(out);
72 size_t result = 0;
73 result += xp.printXMLHeader();
74 result += xp.printNode(
75 "root",
76 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
77 return ((DLNADeviceInfo*)r)->printRoot(o, r);
78 }),
79 this, ns);
80 return result;
81 }
82
83 // sets the device type (ST or NT)
84 void setDeviceType(const char* st) { device_type = st; }
85
86 const char* getDeviceType() { return device_type.c_str(); }
87
89 void setUDN(const char* id) { udn = id; }
90
92 const char* getUDN() { return udn.c_str(); }
93
95 void setBaseURL(const char* url) {
96 DlnaLogger.log(DlnaLogLevel::Info, "Base URL: %s", url);
97 base_url = url;
98 }
99
101 void setBaseURL(IPAddress ip, int port, const char* path = nullptr) {
102 localhost = ip;
103 Str str{80};
104 str = "http://";
105 str += ip[0];
106 str += ".";
107 str += ip[1];
108 str += ".";
109 str += ip[2];
110 str += ".";
111 str += ip[3];
112 str += ":";
113 str += port;
114 if (path != nullptr && !StrView(path).startsWith("/")) {
115 str += "/";
116 }
117 str += path;
118 setBaseURL(str.c_str());
119 }
120
122 const char* getBaseURL() {
123 // replace localhost url
124 if (StrView(base_url).contains("localhost")) {
126 url_str.replace("localhost", getIPStr());
128 }
129 return base_url.c_str();
130 }
131
134 if (!device_url) {
135 Str str = getBaseURL();
136 if (!str.endsWith("/")) str += "/";
137 str += "device.xml";
138 Url new_url(str.c_str());
139 device_url = new_url;
140 }
141 return device_url;
142 }
143
145 void setIPAddress(IPAddress address) { localhost = address; }
146
148 IPAddress getIPAddress() { return localhost; }
149
151 const char* getIPStr() {
152 static char result[80] = {0};
153 snprintf(result, 80, "%d.%d.%d.%d", localhost[0], localhost[1],
154 localhost[2], localhost[3]);
155 return result;
156 }
157
158 void setNS(const char* ns) { this->ns = ns; }
159 const char* getNS() { return ns.c_str(); }
160 void setFriendlyName(const char* name) { friendly_name = name; }
161 const char* getFriendlyName() { return friendly_name.c_str(); }
162 void setManufacturer(const char* man) { manufacturer = man; }
163 const char* getManufacturer() { return manufacturer.c_str(); }
164 void setManufacturerURL(const char* url) { manufacturer_url = url; }
165 const char* getManufacturerURL() { return manufacturer_url.c_str(); }
166 void setModelDescription(const char* descr) { model_description = descr; }
167 const char* getModelDescription() { return model_description.c_str(); }
168 void setModelName(const char* name) { model_name = name; }
169 const char* getModelName() { return model_name.c_str(); }
170 void setModelNumber(const char* number) { model_number = number; }
171 const char* getModelNumber() { return model_number.c_str(); }
172 void setSerialNumber(const char* sn) { serial_number = sn; }
173 const char* getSerialNumber() { return serial_number.c_str(); }
174 void setUniversalProductCode(const char* upc) {
176 }
179 }
180
183 void setDLNACapability(const char* cap) { x_dlnacap = cap; }
184 const char* getDLNACapability() { return x_dlnacap.c_str(); }
185
187 void addService(DLNAServiceInfo s) { services.push_back(s); }
188
190 DLNAServiceInfo& getService(const char* id) {
191 static DLNAServiceInfo result{false};
192 for (auto& service : services) {
193 if (StrView(service.service_id).contains(id)) {
194 return service;
195 }
196 }
197 return result;
198 }
200 DLNAServiceInfo& getServiceByAbbrev(const char* abbrev) {
201 static DLNAServiceInfo result{false};
202 if (services.empty()) return result;
203 for (auto& service : services) {
204 if (StrView(service.subscription_namespace_abbrev).equals(abbrev)) {
205 return service;
206 }
207 }
208 return result;
209 }
210
213
215 void clear() {
216 services.clear();
217 udn = "";
218 ns = "";
219 device_type = "";
220 friendly_name = "";
221 manufacturer = "";
222 manufacturer_url = "";
224 model_name = "";
225 model_number = "";
226 serial_number = "";
228 }
229
231 void clearIcons() { icons.clear(); }
232
234 void addIcon(Icon icon) { icons.push_back(icon); }
235
237 Icon getIcon(int idx = 0) {
238 if (icons.size() == 0) {
239 Icon empty;
240 return empty;
241 }
242 return icons[idx];
243 }
244
247 if (icons.empty()) {
248 // make sure we have at least the default icon
249 Icon icon{"image/png", 48, 48, 24, "/icon.png",
250 (uint8_t*)icon_png, icon_png_len, true};
251 Icon icon128{"image/png",
252 128,
253 128,
254 24,
255 "/icon128.png",
256 (uint8_t*)icon128x128_png,
258 Icon icon512{"image/png",
259 512,
260 512,
261 24,
262 "/icon512.png",
263 (uint8_t*)icon512x512_png,
265 icons.push_back(icon);
266 icons.push_back(icon128);
267 icons.push_back(icon512);
268 }
269
270 return icons;
271 }
272
274 void setActive(bool flag) { is_active = flag; }
275
277 operator bool() { return is_active; }
278
280 virtual bool loop() {
281 delay(1);
282 return true;
283 }
284
286
288
289 protected:
290 bool is_active = false;
292 IPAddress localhost;
295 Str base_url = "http://localhost:9876/dlna";
296 Str udn = "uuid:09349455-2941-4cf7-9847-0dd5ab210e97";
298 "xmlns=\"urn:schemas-upnp-org:device-1-0\" "
299 "xmlns:dlna=\"urn:schemas-dlna-org:device-1-0\"";
315
317 virtual void setupServices(IHttpServer& server, IUDPService& udp) {}
318
319 size_t printRoot(Print& out, void* ref) {
320 XMLPrinter xp(out);
321 size_t result = 0;
322 result += xp.printNode(
323 "specVersion",
324 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
325 return ((DLNADeviceInfo*)r)->printSpecVersion(o, r);
326 }),
327 this);
328 result += xp.printNode("URLBase", base_url);
329 result += xp.printNode(
330 "device",
331 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
332 return ((DLNADeviceInfo*)r)->printDevice(o, r);
333 }),
334 this);
335 return result;
336 }
337
338 size_t printDevice(Print& out, void* ref) {
339 XMLPrinter xp(out);
340 size_t result = 0;
341 result += xp.printNode("deviceType", getDeviceType());
342 result += xp.printNode("friendlyName", friendly_name);
343 result += xp.printNode("manufacturer", manufacturer);
344 result += xp.printNode("manufacturerURL", manufacturer_url);
345 result += xp.printNode("modelDescription", model_description);
346 result += xp.printNode("modelName", model_name);
347 result += xp.printNode("modelNumber", model_number);
348 result += xp.printNode("modelURL", model_url);
349 result += xp.printNode("serialNumber", serial_number);
350 if (!x_dlnacap.isEmpty()) {
351 result += xp.printNode("dlna:X_DLNACAP", x_dlnacap);
352 }
353 result += xp.printNode("UDN", getUDN());
354 result += xp.printNode("UPC", universal_product_code);
355 // use ref-based callbacks that receive Print& and void*
356 result += xp.printNode(
357 "iconList",
358 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
359 return ((DLNADeviceInfo*)r)->printIconList(o, r);
360 }),
361 this);
362 result += xp.printNode(
363 "serviceList",
364 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
365 return ((DLNADeviceInfo*)r)->printServiceList(o, r);
366 }),
367 this);
368 return result;
369 }
370
371 size_t printSpecVersion(Print& out, void* ref) {
372 XMLPrinter xp(out);
373 char major[5], minor[5];
374 sprintf(major, "%d", this->version_major);
375 sprintf(minor, "%d", this->version_minor);
376 return xp.printNode("major", major) + xp.printNode("minor", minor);
377 }
378
379 size_t printServiceList(Print& out, void* ref) {
380 XMLPrinter xp(out);
381 size_t result = 0;
382 for (auto& service : services) {
383 struct Ctx {
384 DLNADeviceInfo* self;
385 DLNAServiceInfo* svc;
386 } ctx{this, &service};
387 result += xp.printNode(
388 "service",
389 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
390 Ctx* c = (Ctx*)r;
391 return c->self->printService(o, c->svc);
392 }),
393 &ctx);
394 }
395 return result;
396 }
397
398 size_t printService(Print& out, void* srv) {
399 XMLPrinter xp(out);
400 size_t result = 0;
401 char buffer[DLNA_MAX_URL_LEN] = {0};
402 StrView url(buffer, DLNA_MAX_URL_LEN);
403 DLNAServiceInfo* service = (DLNAServiceInfo*)srv;
404 result += xp.printNode("serviceType", service->service_type);
405 result += xp.printNode("serviceId", service->service_id);
406 result += xp.printNode("SCPDURL", service->scpd_url);
407 result += xp.printNode("controlURL", service->control_url);
409 result += xp.printNode("eventSubURL", service->event_sub_url);
410 else
411 result += xp.printf("<eventSubURL/>");
412
413 return result;
414 }
415
416 size_t printIconList(Print& out, void* ref) {
417 XMLPrinter xp(out);
418 int result = 0;
419
420 // print all icons
421 for (auto& icon : getIcons()) {
422 struct CtxI {
423 DLNADeviceInfo* self;
424 Icon* icon;
425 } ctx{this, &icon};
426 result += xp.printNode(
427 "icon",
428 std::function<size_t(Print&, void*)>([](Print& o, void* r) -> size_t {
429 CtxI* c = (CtxI*)r;
430 return c->self->printIconDlnaInfo(o, c->icon);
431 }),
432 &ctx);
433 }
434 return result;
435 }
436
437 size_t printIconDlnaInfo(Print& out, Icon* icon) {
438 XMLPrinter xp(out);
439 size_t result = 0;
440 if (!StrView(icon->icon_url).isEmpty()) {
441 char buffer[DLNA_MAX_URL_LEN] = {0};
442 StrView url(buffer, DLNA_MAX_URL_LEN);
443 result += xp.printNode("mimetype", "image/png");
444 result += xp.printNode("width", icon->width);
445 result += xp.printNode("height", icon->height);
446 result += xp.printNode("depth", icon->depth);
447 result += xp.printNode("url", icon->icon_url);
448 }
449 return result;
450 }
451};
452
453} // 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:28
Vector< DLNAServiceInfo > & getServices()
Provides all service definitions.
Definition: DLNADeviceInfo.h:212
Str udn
Definition: DLNADeviceInfo.h:296
Vector< DLNAServiceInfo > services
Definition: DLNADeviceInfo.h:311
Url device_url
Definition: DLNADeviceInfo.h:291
void setModelDescription(const char *descr)
Definition: DLNADeviceInfo.h:166
Str model_number
Definition: DLNADeviceInfo.h:308
size_t printSpecVersion(Print &out, void *ref)
Definition: DLNADeviceInfo.h:371
int version_minor
Definition: DLNADeviceInfo.h:294
Str device_type
Definition: DLNADeviceInfo.h:301
IPAddress localhost
Definition: DLNADeviceInfo.h:292
~DLNADeviceInfo()
Definition: DLNADeviceInfo.h:60
void setDeviceType(const char *st)
Definition: DLNADeviceInfo.h:84
Str universal_product_code
Definition: DLNADeviceInfo.h:310
const char * getFriendlyName()
Definition: DLNADeviceInfo.h:161
Str x_dlnacap
Definition: DLNADeviceInfo.h:300
void addService(DLNAServiceInfo s)
Adds a service definition.
Definition: DLNADeviceInfo.h:187
Str manufacturer_url
Definition: DLNADeviceInfo.h:304
Icon getIcon(int idx=0)
Provides the item at indix.
Definition: DLNADeviceInfo.h:237
void setNS(const char *ns)
Definition: DLNADeviceInfo.h:158
const char * getManufacturer()
Definition: DLNADeviceInfo.h:163
void addIcon(Icon icon)
adds an icon
Definition: DLNADeviceInfo.h:234
const char * getDLNACapability()
Definition: DLNADeviceInfo.h:184
size_t printRoot(Print &out, void *ref)
Definition: DLNADeviceInfo.h:319
void setManufacturerURL(const char *url)
Definition: DLNADeviceInfo.h:164
DLNAServiceInfo & getService(const char *id)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:190
Str url_str
Definition: DLNADeviceInfo.h:313
void clear()
Clears all device information.
Definition: DLNADeviceInfo.h:215
Str ns
Definition: DLNADeviceInfo.h:297
size_t print(Print &out, void *ref=nullptr)
renders the device xml into the provided Print output.
Definition: DLNADeviceInfo.h:70
size_t printService(Print &out, void *srv)
Definition: DLNADeviceInfo.h:398
void clearIcons()
Overwrite the default icon.
Definition: DLNADeviceInfo.h:231
Str base_url
Definition: DLNADeviceInfo.h:295
DLNADeviceInfo(const DLNADeviceInfo &other)
Definition: DLNADeviceInfo.h:38
void setSubscriptionActive(bool flag)
Definition: DLNADeviceInfo.h:285
Str model_name
Definition: DLNADeviceInfo.h:306
const char * getUDN()
Provide the udn uuid.
Definition: DLNADeviceInfo.h:92
const char * getUniversalProductCode()
Definition: DLNADeviceInfo.h:177
void setModelName(const char *name)
Definition: DLNADeviceInfo.h:168
const char * getNS()
Definition: DLNADeviceInfo.h:159
void setSerialNumber(const char *sn)
Definition: DLNADeviceInfo.h:172
const char * getBaseURL()
Provides the base url.
Definition: DLNADeviceInfo.h:122
bool is_subcription_active
Definition: DLNADeviceInfo.h:314
virtual bool begin()
Override to initialize the device.
Definition: DLNADeviceInfo.h:63
const char * getModelDescription()
Definition: DLNADeviceInfo.h:167
Url & getDeviceURL()
This method returns base url/device.xml.
Definition: DLNADeviceInfo.h:133
void setManufacturer(const char *man)
Definition: DLNADeviceInfo.h:162
virtual void setupServices(IHttpServer &server, IUDPService &udp)
to be implemented by subclasses
Definition: DLNADeviceInfo.h:317
Str manufacturer
Definition: DLNADeviceInfo.h:303
void setUDN(const char *id)
Define the udn uuid.
Definition: DLNADeviceInfo.h:89
void setFriendlyName(const char *name)
Definition: DLNADeviceInfo.h:160
IPAddress getIPAddress()
Provides the local IP address.
Definition: DLNADeviceInfo.h:148
Str model_description
Definition: DLNADeviceInfo.h:305
void setActive(bool flag)
Sets the server to inactive.
Definition: DLNADeviceInfo.h:274
void setDLNACapability(const char *cap)
Definition: DLNADeviceInfo.h:183
bool isSubscriptionActive()
Definition: DLNADeviceInfo.h:287
size_t printIconList(Print &out, void *ref)
Definition: DLNADeviceInfo.h:416
Str serial_number
Definition: DLNADeviceInfo.h:309
DLNADeviceInfo(bool ok=true)
Definition: DLNADeviceInfo.h:35
const char * getModelNumber()
Definition: DLNADeviceInfo.h:171
void setIPAddress(IPAddress address)
Defines the local IP address.
Definition: DLNADeviceInfo.h:145
const char * getSerialNumber()
Definition: DLNADeviceInfo.h:173
virtual bool loop()
loop processing
Definition: DLNADeviceInfo.h:280
const char * getModelName()
Definition: DLNADeviceInfo.h:169
void setBaseURL(IPAddress ip, int port, const char *path=nullptr)
Defines the base URL.
Definition: DLNADeviceInfo.h:101
Vector< Icon > icons
Definition: DLNADeviceInfo.h:312
DLNAServiceInfo & getServiceByAbbrev(const char *abbrev)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:200
const char * getManufacturerURL()
Definition: DLNADeviceInfo.h:165
size_t printServiceList(Print &out, void *ref)
Definition: DLNADeviceInfo.h:379
Str model_url
Definition: DLNADeviceInfo.h:307
bool is_active
Definition: DLNADeviceInfo.h:290
Str friendly_name
Definition: DLNADeviceInfo.h:302
size_t printDevice(Print &out, void *ref)
Definition: DLNADeviceInfo.h:338
void setModelNumber(const char *number)
Definition: DLNADeviceInfo.h:170
void setBaseURL(const char *url)
Defines the base url.
Definition: DLNADeviceInfo.h:95
const char * getDeviceType()
Definition: DLNADeviceInfo.h:86
void setUniversalProductCode(const char *upc)
Definition: DLNADeviceInfo.h:174
size_t printIconDlnaInfo(Print &out, Icon *icon)
Definition: DLNADeviceInfo.h:437
int version_major
Definition: DLNADeviceInfo.h:293
Vector< Icon > & getIcons()
Provides all icons.
Definition: DLNADeviceInfo.h:246
const char * getIPStr()
Provides the local address as string.
Definition: DLNADeviceInfo.h:151
Setup of a Basic DLNA Device service. The device registers itself to the network and answers to the D...
Definition: DLNADevice.h:46
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:50
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
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 isEmpty() const
True if empty.
Definition: Str.h:54
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 DEFAULT_DLNA_XCAP
Definition: dlna_config.h:36
#define DLNA_MAX_URL_LEN
app-wide max URL length
Definition: dlna_config.h:61
unsigned int icon128x128_png_len
Definition: icon128x128.h:161
const unsigned char icon128x128_png[]
Definition: icon128x128.h:2
const unsigned char icon_png[]
Definition: icon48x48.h:2
unsigned int icon_png_len
Definition: icon48x48.h:43
unsigned int icon512x512_png_len
Definition: icon512x512.h:1014
const unsigned char icon512x512_png[]
Definition: icon512x512.h:2
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