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