Arduino DLNA Server
Loading...
Searching...
No Matches
DLNAControlPointMediaRenderer.h
Go to the documentation of this file.
1// Header-only control point helper for MediaRenderer devices
2#pragma once
3
4#include <functional>
5
10
11namespace tiny_dlna {
12
24 public:
27
44 IUDPService& udp)
45 : p_mgr(&m), p_http(&http), p_udp(&udp) {}
46
49
56 void setDeviceTypeFilter(const char* filter) {
58 }
60 void setLocalURL(Url url) { p_mgr->setLocalURL(url); }
61
63 void setLocalURL(IPAddress url, int port=9001, const char* path="") {
64 this->p_mgr->setLocalURL(url, port, path);
65 }
66
75 bool begin(uint32_t minWaitMs = 3000, uint32_t maxWaitMs = 60000) {
76 DlnaLogger.log(DlnaLogLevel::Info,
77 "ControlPointMediaRenderer::begin - device_type_filter='%s'",
79 if (!p_mgr) {
80 DlnaLogger.log(DlnaLogLevel::Error, "mgr instance not set");
81 return false;
82 }
83 if (!p_http) {
84 DlnaLogger.log(DlnaLogLevel::Error, "http instance not set");
85 return false;
86 }
87 if (!p_udp) {
88 DlnaLogger.log(DlnaLogLevel::Error, "udp instance not set");
89 return false;
90 }
91 return p_mgr->begin(*p_http, *p_udp, device_type_filter, minWaitMs,
92 maxWaitMs);
93 }
94
100 int count = 0;
101 for (auto& d : p_mgr->getDevices()) {
102 const char* dt = d.getDeviceType();
103 if (!device_type_filter || StrView(dt).contains(device_type_filter))
104 count++;
105 }
106 return count;
107 }
108
113 void setDeviceIndex(int idx) { device_index = idx; }
114
116 bool subscribe() { return p_mgr->subscribe(); }
117
118
120 void setHttp(IHttpRequest& http) { p_http = &http; }
121
123 void setUdp(IUDPService& udp) { p_udp = &udp; }
124
125 typedef void (*NotificationCallback)(void* reference, const char* sid,
126 const char* varName,
127 const char* newValue);
128
130 void setNotificationsActive(bool flag) {
132 }
133
136 std::function<void(const char* sid, const char* varName,
137 const char* newValue, void* reference)>
138 cb,
139 void* ref = nullptr) {
142 }
143
148 void setInstanceID(const char* id) { instance_id = id; }
149
155 bool setMediaURI(const char* uri) {
156 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
157 if (!svc) {
158 DlnaLogger.log(DlnaLogLevel::Error, "No AVTransport service found");
159 return false;
160 }
161 ActionRequest act(svc, "SetAVTransportURI");
162 act.addArgument("InstanceID", instance_id);
163 act.addArgument("CurrentURI", uri);
164 // Some renderers require the CurrentURIMetaData argument to be present
165 // even when empty. Use the Argument constructor to force adding an empty
166 // value (the addArgument(name,value) helper skips empty values).
167 act.addArgument(Argument("CurrentURIMetaData", ""));
168 p_mgr->addAction(act);
170 if (last_reply) {
171 local_url = uri;
172 }
173 return (bool)last_reply;
174 }
175
180 bool play() {
181 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
182 if (!svc) {
183 DlnaLogger.log(DlnaLogLevel::Error, "No AVTransport service found");
184 return false;
185 }
186 ActionRequest act(svc, "Play");
187 act.addArgument("InstanceID", instance_id);
188 act.addArgument("Speed", "1");
189 p_mgr->addAction(act);
191 if (last_reply) {
192 setActiveState(true);
193 local_transport_state = "PLAYING";
194 }
195 return (bool)last_reply;
196 }
197
203 bool play(const char* uri) {
204 if (!setMediaURI(uri)) return false;
205 return play();
206 }
207
212 bool pause() {
213 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
214 if (!svc) return false;
215 ActionRequest act(svc, "Pause");
216 act.addArgument("InstanceID", instance_id);
217 p_mgr->addAction(act);
219 if (last_reply) {
220 setActiveState(false);
221 local_transport_state = "PAUSED_PLAYBACK";
222 }
223 return (bool)last_reply;
224 }
225
230 bool stop() {
231 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
232 if (!svc) return false;
233 ActionRequest act(svc, "Stop");
234 act.addArgument("InstanceID", instance_id);
235 p_mgr->addAction(act);
237 if (last_reply) {
238 setActiveState(false);
239 local_transport_state = "STOPPED";
240 }
241 return (bool)last_reply;
242 }
243
249 bool setVolume(int volumePercent) {
250 if (volumePercent < 0) volumePercent = 0;
251 if (volumePercent > 100) volumePercent = 100;
252 DLNAServiceInfo& svc =
253 selectService("urn:upnp-org:serviceId:RenderingControl");
254 if (!svc) {
255 DlnaLogger.log(DlnaLogLevel::Error, "No RenderingControl service found");
256 return false;
257 }
258 char volBuf[8];
259 snprintf(volBuf, sizeof(volBuf), "%d", volumePercent);
260 ActionRequest act(svc, "SetVolume");
261 act.addArgument("InstanceID", "0");
262 act.addArgument("Channel", "Master");
263 act.addArgument("DesiredVolume", volBuf);
264 p_mgr->addAction(act);
266 if (last_reply) {
267 local_volume = volumePercent;
268 }
269
270 return (bool)last_reply;
271 }
272
278 bool setMute(bool mute) {
279 DLNAServiceInfo& svc =
280 selectService("urn:upnp-org:serviceId:RenderingControl");
281 if (!svc) return false;
282 ActionRequest act(svc, "SetMute");
283 act.addArgument("InstanceID", "0");
284 act.addArgument("Channel", "Master");
285 act.addArgument("DesiredMute", mute ? "1" : "0");
286 p_mgr->addAction(act);
288 if (r) {
289 local_mute = mute;
290 }
291 return (bool)r;
292 }
293
303 int getVolume(bool fromRemote = true) {
304 if (!fromRemote) {
305 return local_volume;
306 }
307 DLNAServiceInfo& svc =
308 selectService("urn:upnp-org:serviceId:RenderingControl");
309 selectService("urn:upnp-org:serviceId:RenderingControl");
310 if (!svc) return -1;
311 ActionRequest act(svc, "GetVolume");
312 act.addArgument("InstanceID", instance_id);
313 p_mgr->addAction(act);
316 if (!last_reply) return -1;
317 const char* v = last_reply.findArgument("CurrentVolume");
318 if (!v) return -1;
319 return atoi(v);
320 }
321
330 int getMute(bool fromRemote = true) {
331 if (!fromRemote) {
332 return local_mute;
333 }
334 DLNAServiceInfo& svc =
335 selectService("urn:upnp-org:serviceId:RenderingControl");
336 if (!svc) return -1;
337 ActionRequest act(svc, "GetMute");
338 act.addArgument("InstanceID", instance_id);
339 act.addArgument("Channel", "Master");
340 p_mgr->addAction(act);
342 if (!last_reply) return -1;
343 const char* m = last_reply.findArgument("CurrentMute");
344 if (!m) return -1;
345 return atoi(m);
346 }
347
352 unsigned long getPositionMs() {
353 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
354 if (!svc) return 0;
355 ActionRequest act(svc, "GetPositionInfo");
356 act.addArgument("InstanceID", instance_id);
357 p_mgr->addAction(act);
359 if (!last_reply) return 0;
360 const char* rel = last_reply.findArgument("RelTime");
361 if (!rel) return 0;
362 return parseTimeToMs(rel);
363 }
364
374 const char* getTransportState(bool fromRemote = true) {
375 if (!fromRemote) {
377 }
378 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
379 if (!svc) return nullptr;
380 ActionRequest act(svc, "GetTransportInfo");
381 act.addArgument("InstanceID", instance_id);
382 p_mgr->addAction(act);
384 if (!last_reply) return nullptr;
385 return last_reply.findArgument("CurrentTransportState");
386 }
387
396 const char* getCurrentURI(bool fromRemote = true) {
397 if (!fromRemote) {
398 return local_url.c_str();
399 }
400 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
401 if (!svc) return nullptr;
402 ActionRequest act(svc, "GetMediaInfo");
403 act.addArgument("InstanceID", instance_id);
404 p_mgr->addAction(act);
406 if (!last_reply) return nullptr;
407 return last_reply.findArgument("CurrentURI");
408 }
409
415 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
416 if (!svc) return -1;
417 ActionRequest act(svc, "GetMediaInfo");
418 act.addArgument("InstanceID", instance_id);
419 p_mgr->addAction(act);
421 if (!last_reply) return -1;
422 const char* n = last_reply.findArgument("NrTracks");
423 if (!n) return -1;
424 return atoi(n);
425 }
426
431 unsigned long getMediaDurationMs() {
432 DLNAServiceInfo& svc =
433 p_mgr->getService("urn:upnp-org:serviceId:AVTransport");
434 if (!svc) return 0;
435 ActionRequest act(svc, "GetMediaInfo");
436 act.addArgument("InstanceID", instance_id);
437 p_mgr->addAction(act);
439 if (!last_reply) return 0;
440 const char* d = last_reply.findArgument("MediaDuration");
441 if (!d) return 0;
442 return parseTimeToMs(d);
443 }
444
450 DLNAServiceInfo& svc =
451 p_mgr->getService("urn:upnp-org:serviceId:AVTransport");
452 if (!svc) return -1;
453 ActionRequest act(svc, "GetPositionInfo");
454 act.addArgument("InstanceID", instance_id);
455 p_mgr->addAction(act);
457 if (!last_reply) return -1;
458 const char* tr = last_reply.findArgument("Track");
459 if (!tr) return -1;
460 return atoi(tr);
461 }
462
467 unsigned long getTrackDurationMs() {
468 DLNAServiceInfo& svc =
469 p_mgr->getService("urn:upnp-org:serviceId:AVTransport");
470 if (!svc) return 0;
471 ActionRequest act(svc, "GetPositionInfo");
472 act.addArgument("InstanceID", instance_id);
473 p_mgr->addAction(act);
475 if (!last_reply) return 0;
476 const char* td = last_reply.findArgument("TrackDuration");
477 if (!td) return 0;
478 return parseTimeToMs(td);
479 }
480
485 const ActionReply& getLastReply() const { return last_reply; }
486
491 bool isActive() { return is_active; }
492
497 void setReference(void* ref) { reference = ref; }
498
504 void onActiveChanged(std::function<void(bool, void*)> cb) {
506 }
507
515 DLNAServiceInfo& svc = selectService("urn:upnp-org:serviceId:AVTransport");
516 if (!svc) {
517 DlnaLogger.log(DlnaLogLevel::Error, "No AVTransport service found");
518 return false;
519 }
520 ActionRequest act(svc, "GetCurrentTransportActions");
521 act.addArgument("InstanceID", instance_id);
522 p_mgr->addAction(act);
524 if (!last_reply) return false;
525 const char* actions = last_reply.findArgument("Actions");
526 if (!actions) return false;
527 out = actions;
528 return true;
529 }
530
539 std::function<void(const char* entry, ProtocolRole role)> cb) {
540 if (!cb) return false;
541
542 DLNAServiceInfo& svc =
543 p_mgr->getService("urn:upnp-org:serviceId:ConnectionManager");
544 if (!svc) {
545 DlnaLogger.log(DlnaLogLevel::Error, "No ConnectionManager service found");
546 return false;
547 }
548
549 // build action and enqueue
550 ActionRequest act(svc, "GetProtocolInfo");
551 p_mgr->addAction(act);
552 bool ok = false;
553
554 // processor will be invoked with the live Client and the ActionReply so
555 // callers can handle the response stream themselves. We simply stream-
556 // parse and forward each parsed entry to the provided callback.
557 XMLCallback processor = [&cb, &ok](Client& client, ActionReply& reply) {
558 ok = XMLProtocolInfoParser::parse(client, cb);
559 reply.clear();
560 reply.setValid(true);
561 };
562
563 // execute the queued action and use our processor to handle the reply
564 p_mgr->executeActions(processor);
565 return ok;
566 }
567
568 protected:
570 bool is_active = false;
571 std::function<void(bool, void*)> activeChangedCallback = nullptr;
573 const char* instance_id = "0";
575 "urn:schemas-upnp-org:device:MediaRenderer:1";
578 void* reference = nullptr;
579 // Optional transport references (must be set before calling begin())
581 IUDPService* p_udp = nullptr;
583 int local_mute = false;
585 const char* local_transport_state = "STOPPED";
586
587 // Helper to update is_active and notify callback only on change
588 void setActiveState(bool s) {
589 if (is_active == s) return;
590 is_active = s;
591 DlnaLogger.log(DlnaLogLevel::Info, "ControlPointMediaRenderer active=%s",
592 is_active ? "true" : "false");
594 }
595
597 static void processNotification(void* reference, const char* sid,
598 const char* varName, const char* newValue) {
599 // Log every notification invocation for debugging/visibility
600 DlnaLogger.log(DlnaLogLevel::Info,
601 "processNotification sid='%s' var='%s' value='%s'",
602 sid ? sid : "(null)", varName ? varName : "(null)",
603 newValue ? newValue : "(null)");
604
607 if (renderer) {
608 // Handle the notification (e.g., update internal state, call callbacks)
609 if (StrView(varName) == "TransportState") {
610 if (StrView(newValue) == "PLAYING") {
611 renderer->setActiveState(true);
612 } else {
613 renderer->setActiveState(false);
614 }
615 }
616 }
617 }
618
619 // Helper: parse DLNA time string (HH:MM:SS, MM:SS) to milliseconds
620 static unsigned long parseTimeToMs(const char* t) {
621 if (t == nullptr) return 0;
622 int h = 0, m = 0, s = 0;
623 int parts = 0;
624 // Count colons
625 const char* p = t;
626 int colonCount = 0;
627 while (*p) {
628 if (*p == ':') colonCount++;
629 p++;
630 }
631 if (colonCount == 2) {
632 parts = sscanf(t, "%d:%d:%d", &h, &m, &s);
633 } else if (colonCount == 1) {
634 parts = sscanf(t, "%d:%d", &m, &s);
635 h = 0;
636 } else {
637 // maybe it's seconds only
638 parts = sscanf(t, "%d", &s);
639 }
640 if (parts <= 0) return 0;
641 unsigned long total =
642 (unsigned long)h * 3600UL + (unsigned long)m * 60UL + (unsigned long)s;
643 return total * 1000UL;
644 }
645
648 // use selected device
650 if (s) return s;
651
652 // fallback: global search
653 return p_mgr->getService(id);
654 }
655};
656
657} // namespace tiny_dlna
Represents the result of invoking a DLNA service Action.
Definition: Action.h:48
const char * findArgument(const char *name)
Definition: Action.h:70
Represents a request to invoke a remote DLNA service action.
Definition: Action.h:104
void addArgument(Argument arg)
Definition: Action.h:113
DLNA Service: Action Argument.
Definition: Action.h:17
Class to control a MediaRenderer device from a control point.
Definition: DLNAControlPointMediaRenderer.h:23
bool setMute(bool mute)
Set mute state on the renderer.
Definition: DLNAControlPointMediaRenderer.h:278
const ActionReply & getLastReply() const
Return last ActionReply (from the most recent synchronous call)
Definition: DLNAControlPointMediaRenderer.h:485
const char * getCurrentURI(bool fromRemote=true)
Get the current media URI from the renderer.
Definition: DLNAControlPointMediaRenderer.h:396
bool play()
Start playback on the renderer.
Definition: DLNAControlPointMediaRenderer.h:180
int getMute(bool fromRemote=true)
Query mute state.
Definition: DLNAControlPointMediaRenderer.h:330
bool setVolume(int volumePercent)
Set renderer volume.
Definition: DLNAControlPointMediaRenderer.h:249
const char * local_transport_state
Definition: DLNAControlPointMediaRenderer.h:585
int local_mute
Definition: DLNAControlPointMediaRenderer.h:583
void setDeviceIndex(int idx)
Select the active renderer by index (0-based)
Definition: DLNAControlPointMediaRenderer.h:113
IUDPService * p_udp
Definition: DLNAControlPointMediaRenderer.h:581
int local_volume
Definition: DLNAControlPointMediaRenderer.h:582
void(* NotificationCallback)(void *reference, const char *sid, const char *varName, const char *newValue)
Definition: DLNAControlPointMediaRenderer.h:125
void setReference(void *ref)
Attach an opaque reference object that will be passed to callbacks.
Definition: DLNAControlPointMediaRenderer.h:497
DLNAControlPointMediaRenderer(DLNAControlPoint &m, IHttpRequest &http, IUDPService &udp)
Construct helper with references to control point manager and transport instances.
Definition: DLNAControlPointMediaRenderer.h:43
bool stop()
Stop playback.
Definition: DLNAControlPointMediaRenderer.h:230
unsigned long getPositionMs()
Query current playback position (RelTime)
Definition: DLNAControlPointMediaRenderer.h:352
bool is_active
Definition: DLNAControlPointMediaRenderer.h:570
int device_index
Definition: DLNAControlPointMediaRenderer.h:572
void setNotificationsActive(bool flag)
Activate/deactivate subscription notifications.
Definition: DLNAControlPointMediaRenderer.h:130
const char * getTransportState(bool fromRemote=true)
Query transport state (e.g. STOPPED, PLAYING, PAUSED_PLAYBACK).
Definition: DLNAControlPointMediaRenderer.h:374
unsigned long getTrackDurationMs()
Get current track duration in milliseconds (from TrackDuration)
Definition: DLNAControlPointMediaRenderer.h:467
DLNAServiceInfo & selectService(const char *id)
Select service by id.
Definition: DLNAControlPointMediaRenderer.h:647
void setDeviceTypeFilter(const char *filter)
Restrict this helper to devices of the given device type.
Definition: DLNAControlPointMediaRenderer.h:56
bool pause()
Pause playback.
Definition: DLNAControlPointMediaRenderer.h:212
static void processNotification(void *reference, const char *sid, const char *varName, const char *newValue)
Notification callback.
Definition: DLNAControlPointMediaRenderer.h:597
int getVolume(bool fromRemote=true)
Query the current volume from the renderer.
Definition: DLNAControlPointMediaRenderer.h:303
Str local_url
Definition: DLNAControlPointMediaRenderer.h:584
void * reference
Definition: DLNAControlPointMediaRenderer.h:578
ActionReply last_reply
Definition: DLNAControlPointMediaRenderer.h:577
const char * device_type_filter
Definition: DLNAControlPointMediaRenderer.h:576
void setLocalURL(Url url)
Defines the local URL for the control point.
Definition: DLNAControlPointMediaRenderer.h:60
static unsigned long parseTimeToMs(const char *t)
Definition: DLNAControlPointMediaRenderer.h:620
bool isActive()
Query if the helper considers the renderer to be actively playing.
Definition: DLNAControlPointMediaRenderer.h:491
bool subscribe()
Subscribe to event notifications: call after selecting the device.
Definition: DLNAControlPointMediaRenderer.h:116
int getDeviceCount()
Return the number of discovered devices matching the renderer filter.
Definition: DLNAControlPointMediaRenderer.h:99
bool getCurrentTransportActions(Str &out)
Query the AVTransport service for the current transport actions and return the raw Actions list into ...
Definition: DLNAControlPointMediaRenderer.h:514
bool play(const char *uri)
Set the media URI and start playback.
Definition: DLNAControlPointMediaRenderer.h:203
int getTrackIndex()
Get current track index (from GetPositionInfo)
Definition: DLNAControlPointMediaRenderer.h:449
IHttpRequest * p_http
Definition: DLNAControlPointMediaRenderer.h:580
void setHttp(IHttpRequest &http)
Setter for the HTTP wrapper used for subscriptions and callbacks.
Definition: DLNAControlPointMediaRenderer.h:120
const char * instance_id
Definition: DLNAControlPointMediaRenderer.h:573
unsigned long getMediaDurationMs()
Get total media duration in milliseconds (from MediaDuration)
Definition: DLNAControlPointMediaRenderer.h:431
void onActiveChanged(std::function< void(bool, void *)> cb)
Register a callback invoked when the active (playing) state changes.
Definition: DLNAControlPointMediaRenderer.h:504
void setLocalURL(IPAddress url, int port=9001, const char *path="")
Defines the local URL for the control point.
Definition: DLNAControlPointMediaRenderer.h:63
void setActiveState(bool s)
Definition: DLNAControlPointMediaRenderer.h:588
bool getProtocalInfo(std::function< void(const char *entry, ProtocolRole role)> cb)
Fetch protocol-info via SOAP GetProtocolInfo on the ConnectionManager service and invoke cb for each ...
Definition: DLNAControlPointMediaRenderer.h:538
void setInstanceID(const char *id)
Set the InstanceID used for AVTransport and RenderingControl actions.
Definition: DLNAControlPointMediaRenderer.h:148
bool setMediaURI(const char *uri)
Set the media URI on the renderer.
Definition: DLNAControlPointMediaRenderer.h:155
int getNrTracks()
Get number of tracks in the current media.
Definition: DLNAControlPointMediaRenderer.h:414
void setUdp(IUDPService &udp)
Setter for UDP service used for discovery (SSDP)
Definition: DLNAControlPointMediaRenderer.h:123
DLNAControlPoint * p_mgr
Definition: DLNAControlPointMediaRenderer.h:569
std::function< void(bool, void *)> activeChangedCallback
Definition: DLNAControlPointMediaRenderer.h:571
bool begin(uint32_t minWaitMs=3000, uint32_t maxWaitMs=60000)
Begin discovery and processing.
Definition: DLNAControlPointMediaRenderer.h:75
void setDLNAControlPoint(DLNAControlPoint &m)
Set the control point manager instance (required before using helper)
Definition: DLNAControlPointMediaRenderer.h:48
void setNotificationCallback(std::function< void(const char *sid, const char *varName, const char *newValue, void *reference)> cb, void *ref=nullptr)
Register a callback for notifications and activate subscriptions.
Definition: DLNAControlPointMediaRenderer.h:135
DLNAControlPointMediaRenderer()=default
Default constructor.
const char * device_type_filter_default
Definition: DLNAControlPointMediaRenderer.h:574
Lightweight DLNA control point manager.
Definition: DLNAControlPoint.h:61
void setLocalURL(Url url) override
Defines the local url (needed for subscriptions)
Definition: DLNAControlPoint.h:89
DLNAServiceInfo & getService(const char *id) override
Provide addess to the service information.
Definition: DLNAControlPoint.h:361
void setEventSubscriptionCallback(std::function< void(const char *sid, const char *varName, const char *newValue, void *reference)> cb, void *ref=nullptr) override
Register a callback that will be invoked for incoming event notification.
Definition: DLNAControlPoint.h:110
DLNADeviceInfo & getDevice() override
Provides the device information of the actually selected device.
Definition: DLNAControlPoint.h:372
Vector< DLNADeviceInfo > & getDevices() override
Get list of all discovered devices.
Definition: DLNAControlPoint.h:414
void setNotificationsActive(bool flag) override
Activate/deactivate subscription notifications.
Definition: DLNAControlPoint.h:519
bool begin(const char *searchTarget="ssdp:all", uint32_t minWaitMs=3000, uint32_t maxWaitMs=60000) override
Start discovery with default HTTP/UDP services.
Definition: DLNAControlPoint.h:133
ActionReply & executeActions(XMLCallback xmlProcessor=nullptr) override
Executes action and parses the reply xml to collect the reply entries. If an XML processor is provide...
Definition: DLNAControlPoint.h:304
ActionRequest & addAction(ActionRequest act) override
Registers a method that will be called.
Definition: DLNAControlPoint.h:290
bool subscribe()
Subscribes to event notifications for all services of the selected device.
Definition: DLNAControlPoint.h:216
DLNAServiceInfo & getService(const char *id)
Finds a service definition by name.
Definition: DLNADeviceInfo.h:183
Attributes needed for the DLNA Service Definition.
Definition: DLNAServiceInfo.h:18
Abstract interface for HTTP client request functionality.
Definition: IHttpRequest.h:21
Abstract Interface for UDP API.
Definition: IUDPService.h:33
A simple wrapper to provide string functions on char*. If the underlying char* is a const we do not a...
Definition: StrView.h:18
Heap-backed string utility used throughout tiny_dlna.
Definition: Str.h:27
const char * c_str() const
C-string pointer to internal buffer.
Definition: Str.h:88
URL parser which breaks a full url string up into its individual parts.
Definition: Url.h:18
static bool parse(Stream &in, std::function< void(const char *entry, ProtocolRole role)> cb)
Definition: XMLProtocolInfoParser.h:41
Definition: Allocator.h:13
ProtocolRole
Role to indicate whether a protocolInfo entry is a Source or a Sink.
Definition: DLNACommon.h:26
std::function< void(Client &client, ActionReply &reply)> XMLCallback
Definition: IControlPoint.h:25